Node HTTP request for Restful api's that retur

2019-01-25 09:28发布

问题:

I am attempting to make server side calls to restful API's using node.js. Returns with JSONP (JSON container inside a JS function) are returning errors that seems to be at the heart of the node http.get(options, callback) API. Can node or any module return the JSON object from a JSONP return?

Example JSONP request: http://www.linkedin.com/countserv/count/share?url=http://techcrunch.com/2012/01/29/turning-two-founderscard-pulls-back-the-curtain-on-its-membership-community-for-entrepreneurs/

回答1:

Execute the callback with vm

JavaScript code can be compiled and run immediately or compiled, saved, and run later

A previous answer suggests striping the callback function. Unfortunately, this is not compatible with many jsonp responses since the contents of the function are usually objects and not pure JSON. The JSON.parse() function will die for something like the following:

callback({key:"value"});

While the above is a valid object, it is not valid JSON.

The following will execute the callback and return the object:

jsonpSandbox = vm.createContext({callback: function(r){return r;}});
myObject = vm.runInContext(jsonpData,jsonpSandbox);

When creating the context change callback to the name of the callback function that is returned in the jsonp response.



回答2:

I'd write a wrapper function that checks for JSON and strips the function off the returned string just to avoid running eval. Then JSON.parse on the string (now minus the function since we removed it) to return json.

var request = require('request');
var getJsonFromJsonP = function (url, callback) {
request(url, function (error, response, body) {
  if (!error && response.statusCode == 200) {
    var jsonpData = body;
    var json;
    //if you don't know for sure that you are getting jsonp, then i'd do something like this
    try
    {
       json = JSON.parse(jsonpData);
    }
    catch(e)
    {
        var startPos = jsonpData.indexOf('({');
        var endPos = jsonpData.indexOf('})');
        var jsonString = jsonpData.substring(startPos+1, endPos+1);
        json = JSON.parse(jsonString);
    }
    callback(null, json);
  } else {
    callback(error);
  }
})
}

Then use it like so:

getJsonFromJsonP('http://www.linkedin.com/countserv/count/share?url=http://techcrunch.com/2012/01/29/turning-two-founderscard-pulls-back-the-curtain-on-its-membership-community-for-entrepreneurs/', function (err, data) {
    console.log('data count', data.count);
});