"Unexpected token in JSON at position 0" 在具有有效 JSON 的节点中使用 JSON.parse

"Unexpected token in JSON at position 0" using JSON.parse in Node with valid JSON

几个小时以来,我一直在为这个问题焦头烂额。

我有一个简单的节点服务器,它正在调用外部 API 以获得 JSON 的(大量的,如 4+ MB)位。我正在使用尽可能多的样板请求,直接取自 Node 文档:

const muniURL = `http://api.511.org/transit/vehiclemonitoring?api_key=${API_KEYS.API_KEY_511}&format=json&agency=sf-muni`;

http.get(muniURL, (res) => {
  const statusCode = res.statusCode;
  const contentType = res.headers['content-type'];
  console.log('Status Code:', statusCode);
  console.log('Content Type:', contentType);

  let error;
  if (statusCode !== 200) {
    error = new Error(`Request Failed.\n` +
                      `Status Code: ${statusCode}`);
  } else if (!/^application\/json/.test(contentType)) {
    error = new Error(`Invalid content-type.\n` +
                      `Expected application/json but received ${contentType}`);
  }
  if (error) {
    console.log(`Request error: ${error.message}`);
    // consume response data to free up memory
    res.resume();
    return;
  }

  res.setEncoding('utf8');
  let rawData = '';
  res.on('data', (chunk) => rawData += chunk);
  res.on('end', () => {
    try {
      const parsedData = JSON.parse(rawData);
      console.log('parsedData:', parsedData);
    } catch (e) {
      console.log(`Caught error: ${e.message}`);
    }
  });
}).on('error', (e) => {
  console.log(`Got error: ${e.message}`);
});

...并且每一次,它都会命中 catch 语句: Caught error: Unexpected token in JSON at position 0。 (注意 'token' 和 'in' 之间的两个 space。)

我已经用两个不同的基于网络的 JSON 验证器检查了从 Chrome 和 Postman 返回的 JSON,结果返回为有效。将 rawData 写入文件时看起来像缓冲区(?)...

1fef bfbd 0800 0000 0000 0400 efbf bdef
bfbd efbf bd72 efbf bdc8 b62d efbf bd2b
0c3f 7547 1cef bfbd 00ef bfbd efbf bd0b
efbf bd5b 49ef bfbd 2def bfbd 6c6b efbf
bd5c 55ef bfbd efbf bd44 3fef bfbd 126c
71ef bfbd 021c 2029 6def bfbd 13ef bfbd
efbf bdef bfbd 437f 52ef bfbd 4227 48ef
bfbd efbf bd4d efbf bd31 13ef bfbd 09ef
bfbd 5d2f 7bef bfbd efbf bde5 aa81 745e
efbf bd65 efbf bd31 efbf bdef bfbd efbf
...

...Buffer.isBuffer 返回错误。

到目前为止,我已经尝试先 JSON.stringifying,toStringing,转换为 new Buffer,然后字符串化,.triming white space , 和 replaceing 各种转义字符,都无济于事。

我在这里错过了什么?


编辑:我意识到我正在验证 Chrome 和 Postman 获取的 JSON,它们显然正在进行某种预处理。 curling URL 会产生一大堆乱七八糟的东西,这绝对不是 JSON。仍然存在这样的问题,即混乱实际上是什么数据类型,以及为什么我在特别请求它时没有得到 JSON。

似乎 api。511.org 正在将 gzip 应用于提供有效 api_key 的任何 api 调用。它还在 json 响应中返回无效的第一个字符。

解决方法如下:

var request = require('request');

var apiUrl = 'http://api.511.org/transit/vehiclemonitoring?api_key=${API_KEYS.API_KEY_511}&format=json&agency=sf-muni';
//apiUrl = 'http://ip.jsontest.com/';

var response = request({
    method: 'GET',
    uri: apiUrl,
    gzip: true
}, function(error, response, body) {
    //* workaround for issue with this particular apiUrl
    var firstChar = body.substring(0, 1);
    var firstCharCode = body.charCodeAt(0);
    if (firstCharCode == 65279) {
        console.log('First character "' + firstChar + '" (character code: ' + firstCharCode + ') is invalid so removing it.');
        body = body.substring(1);
    }
    //*/

    var parsedJson = JSON.parse(body);
    console.log('parsedJson: ', parsedJson);
});