我正在尝试使用Google的网址缩短API。 我正在使用此代码使用节点JS缩短它:
function _shorten (url, callback) {
if (!url) {
console.error('Please specify a valid url.');
return;
}
if (typeof _url.parse(url).protocol === 'undefined') {
url = 'http://' + url;
}
if (!callback) { callback = false; }
var key = _getKey(),
options = {
host: 'www.googleapis.com',
port: 443,
path: '/urlshortener/v1/url' + (key ? '?' + _querystring.stringify({'key': key}) : ''),
method: 'POST',
headers: {
'content-type': 'application/json'
}
};
var req = _https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (d) {
d = JSON.parse(d); // <--- here is the problem
if (callback) {
callback(d);
} else {
console.log(d.id || d.error);
}
});
});
req.on('error', function(e) { console.error(e); });
req.write(JSON.stringify({'longUrl': url}));
req.end();
}
但是,当我尝试使用基本URL运行它时,我收到以下错误:
undefined:1
{
^
SyntaxError: Unexpected end of input
at Object.parse (native)
at IncomingMessage.<anonymous> (/Users/PATH/node_modules/goo.gl/lib/googl.js:45:26)
at IncomingMessage.EventEmitter.emit (events.js:95:17)
at IncomingMessage.<anonymous> (_stream_readable.js:746:14)
at IncomingMessage.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at IncomingMessage.Readable.push (_stream_readable.js:127:10)
at HTTPParser.parserOnBody [as onBody] (http.js:142:22)
我相信这是因为我在完全收到数据之前试图解析收到的数据。当我删除d = JSON.parse(d);我的回调被多次调用,我得到以下结果:
{
"
k
i
n
d
"
:
"
u
r
l
s
hortener#url",
"id": "http://goo.gl/test",
"longUrl": "http://test.com"
}
我该如何解决这个问题?我应该做这样的事情,因为我只对'id'字段感兴趣吗?:
if d contains 'id' then
d = JSON.parse(d);
if (callback) {
callback(d);
} else {
console.log(d.id || d.error);
}
感谢
答案 0 :(得分:0)
您需要累积数据直到完成,然后执行JSON.parse()
。因此,您要继续在.on('data',...)
事件处理程序中扩充数据,并且需要在JSON.parse()
事件处理程序中传输callback
和.on('end',...)
存在检查。
来自http.ClientRequest上的Nodejs文档:
However, if you add a 'response' event handler, then you must consume the data from the
response object, either by calling response.read() whenever there is a 'readable' event,
or by adding a 'data' handler, or by calling the .resume() method. Until the data is
consumed, the 'end' event will not fire. Also, until the data is read it will consume
memory that can eventually lead to a 'process out of memory' error.
答案 1 :(得分:0)
好的,我设法解决了这个问题:
var req = _https.request(options, function(res) {
var message = "";
var id = "id";
res.setEncoding('utf8');
res.on('data', function (d) {
message += d;
var idIndex = message.indexOf(id);
var didFindId = idIndex != -1;
if (didFindId) {
if (callback) {
message = JSON.parse(message);
callback(message);
} else {
console.log(d.id || d.error);
}
}
});
});
我检查我的数据是否包含&#34; id&#34;累积到目前为止收到的所有数据后,我才发送