Node HTTP-запрос для Restful api, который возвращает JSONP

Я пытаюсь сделать серверные вызовы для успокоительного API с помощью node.js. Возвраты с JSONP (контейнер JSON внутри JS-функции) возвращают ошибки, которые, по-видимому, лежат в основе API node http.get(options, callback). Может ли node или любой модуль вернуть объект JSON из возврата JSONP?

Пример запроса JSONP: 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

Выполните обратный вызов с помощью vm

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

Предыдущий ответ предполагает чередование функции обратного вызова. К сожалению, это несовместимо со многими ответами jsonp, поскольку содержимое функции обычно является объектами, а не чистым JSON. Функция JSON.parse() умрет за что-то вроде следующего:

callback({key:"value"});

В то время как выше это действительный объект, он недействителен JSON.

Следующее выполнит обратный вызов и вернет объект:

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

При создании изменения контекста callback в качестве имени функции обратного вызова, возвращаемой в ответ jsonp.

Ответ 2

Я бы написал функцию-оболочку, которая проверяет JSON и отбрасывает функцию из возвращаемой строки, чтобы избежать использования eval. Затем JSON.parse на строке (теперь минус функция, так как мы ее удалили), чтобы вернуть 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);
  }
})
}

Затем используйте его так:

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);
});