Closed mgd216 closed 13 years ago
Tom,
I took a shot at adding this functionality. In file rest.js on line 17, I modified the app.get method to be:
/**
Query */ app.get('/:db/:collection/:id?', function(req, res) { var query = req.query.query ? JSON.parse(req.query.query) : {};
// Providing an id overwrites giving a query in the URL if (req.params.id) { query = {'_id': new mongo.ObjectID(req.params.id)}; } var options = req.params.options || {};
var test = ['limit','sort','fields','skip','hint','explain','snapshot','timeout'];
for( o in req.query ) { if( test.indexOf(o) >= 0 ) { //remove the callback method from the query parameters if (!req.query.callback){ options[o] = req.query[o]; } } }
var db = new mongo.Db(req.params.db, new mongo.Server(config.db.host, config.db.port, {'auto_reconnect':true}));
db.open(function(err,db) {
db.collection(req.params.collection, function(err, collection) {
collection.find(query, options, function(err, cursor) {
cursor.toArray(function(err, docs){
var result = [];
if(req.params.id) {
if(docs.length > 0) {
result = util.flavorize(docs[0], "out");
} else {
res.send(404);
}
} else {
docs.forEach(function(doc){
result.push(util.flavorize(doc, "out"));
});
}
res.header('Content-Type', 'application/json');
if(req.query.callback) {
//remove the [] from the beginning and end of the response
wrappedResult = JSON.stringify(result);
wrappedResult = wrappedResult.substring(1,(wrappedResult.length -1));
res.send(req.query.callback + "(" + wrappedResult + ")");
} else {
res.send(result);
}
db.close();
});
});
});
});
});
I updated my jQuery method to be:
(function(){
// @namespace LKS top level namespace
LKS={};
LKS.params={};
//url to the webservice
LKS.params.url='http://localhost:3000/foo/bar/?callback=LKS.draw';
LKS.start= function(){
//jsonp call
$.jsonp( {'url':LKS.params.url});
}
LKS.draw = function(data){
html = "<b>TEST Results: " + JSON.stringify(data) + "</br></b>"
html = "<b>ID: " + data._id + "</br></b>"
$("#test").append(html);
};
}());
When I called mongodb-rest with the callback=? value, it worked like a charm. Hopefully you think this is a worthy change, thanks again.
Matt
PS Sorry... new to GitHub too, can't figure out how to block code in comments, sorry hard to read.
+1 for jsonp, cross-site callbacks are useful
just for the record, I think there's a another method for cross-site callbacks, using the HTTP protocol, the drawback is that older browsers don't support this. http://ejohn.org/blog/the-march-of-access-control/ supporting this seems pretty easy, it only requires to add an http header:
Access-Control-Allow-Origin: *
or allowing a custom domain like:
Access-Control-Allow-Origin: http://mywebpageserver.com
to all responses, of course this should be an opt-in configuration, but probably this is for another feature, sorry
I am trying to create a website using jQuery where my application is on a different server than mongodb-rest. In order to query mongodb-rest on another server, it has to be able to support JSONP. There is a really good example of this here:
http://www.jsonpexamples.com/jsonp-rating-example-using-jquery/
In short, JSONP wraps the JSON response in a callback method. For example, using mongodb-rest as it is today I get:
Call: http://localhost:3000/foo/bar/ Response: [{"_id":"4d91e32a7a3a4172cd000000","x":1}]
To support JSONP, you need to add the callback method to the Call and then wrap the response with the method name. For example:
Call: http://localhost:3000/foo/bar/?callback=writeResponse Response: writeResponse({"_id":"4d91e32a7a3a4172cd000000","x":1})
Then my jQuery method writeResponse(data) can parse the JSON and complete processing.
The implementation doesn't seem to bad: 1.) Parse incoming request URL, if the term "callback=?" is found, save the callback value to wrap the JSON response. 2.) Pull JSON from Mongo and instead of responding with [{myjson}], the response would be myFunction({myjson}).
Thanks for your help.
Matt