2015-06-14 13 views
-1

Я пытаюсь изучить nodejs и иметь эту страницу, которая должна распечатать все репозиции, которые есть у кого-то в GitHub. Сейчас он случайно останавливается на полпути через сообщение, поэтому, если я попытаюсь разобрать его в JSON, это не сработает.Получение неполного ответа от API GitHub

var http = require('http'); 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    var https = require('https'); 
    var options = { 
    host: 'api.github.com', 
    headers: {'user-agent': 'GitHubAPI'}, 
    path: '/users/vermiculus/repos' 
    }; 
    var gitapi = https.get(options, function(git) { 
    git.on("data", function(chunk) { 
     //JSON.parse(chunk); //DEBUG Fails and dies. 
     res.end(chunk); 
    }); 
    }); 
}).listen(1337, '127.0.0.1'); 
console.log('Server running at http://127.0.0.1:1337/'); 

Редактировать: Вот пример ответа. Посмотрите, как буквально останавливается в середине строки.

[{"id":24659454,"name":"arara","full_name":"vermiculus/arara","owner":{"login":"vermiculus","id":2082195,"avatar_url":"https://avatars.githubusercontent.com/u/2082195?v=3","gravatar_id":"","url":"https://api.github.com/users/vermiculus","html_url":"https://github.c 
+0

Любой уход объяснить downvote? –

ответ

2

data события для объекта отклика https.get() может вызываться несколько раз, но вы окончание ответа вашего HTTP-сервера после первой.

Вы должны собрать все куски и объединить их в end обработчика:

var gitapi = https.get(options, function(git) { 
    var chunks = []; 

    git.on("data", function(chunk) { 
    chunks.push(chunk); 
    }); 

    git.on("end", function() { 
    var json = Buffer.concat(chunks); 
    res.end(json); 
    }); 
}); 

FWIW, если данные API GH является JSON, установка text/plain типа, как содержание не делает много смысла.

Если вы просто хотите, чтобы прокси ответов GH, вы можете также использовать pipe() (который в основном делает то же самое, что и выше, только более эффективно):

var gitapi = https.get(options, function(git) { 
    git.pipe(res); 
}); 
+0

Это немного удивительно для меня, что это не делается немного больше «автоматически» в духе XMLHTTPRequest, где вы можете по крайней мере установить обратный вызов и получить ответ где-то без необходимости вручную конкатенировать куски. – kzahel

+0

@kzahel Я согласен, что это немного низкий уровень, но он также позволяет обрабатывать потоки (или трубопроводы), которые не требуют, чтобы весь ответ сначала считывался в память. Для облегчения работы существуют различные модули (например, ['stream-collect'] (https://www.npmjs.com/package/stream-collect) или [' collect-stream'] (https: // www. npmjs.com/package/collect-stream)), чтобы скрыть внутренние элементы. – robertklep

+0

@robertklep: Это, вероятно, просто Haskell развращает меня, но почему не 'git.on (« data », chunks.push);« работать как альтернатива созданию анонимной функции? –

1

Вы используете res.end после того, как получите кусок данных. Попробуйте объединить все куски в одну строку, прежде чем разбирать ее.

var gitapi = https.get(options, function(git) { 
var body = ''; 
git.on("data", function(chunk) { 
    body += chunk.toString('utf8'); 
}); 
git.on("end", function() { 
    //var json = JSON.parse(body) 
    res.end(body); 
}); 
}); 
Смежные вопросы