web-dev-qa-db-ja.com

「有効なJSONでNodeのJSON.parseを使用して位置0のJSONに予期しないトークンがあります

何時間もこの髪の毛を引き裂いてきました。

私は単純なNodeサーバーが外部APIを呼び出して、4 MB以上の大容量)のJSONビットを取得しています。できる限り、リクエストをボイラープレートとして使用していますNode docsから直接取得:

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'の間の2つのスペースに注意してください。)

ChromeとPostmanの両方から返されたJSONを2つの異なるWebベースの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はfalseを返します。

これまでのところ、私は最初にJSON.stringifying、toStringing、new Bufferに変換してから文字列化、.triming空白、およびreplaceingをあらゆる種類のエスケープされた文字、すべて役に立たない。

ここで何が欠けていますか?


編集:私はChromeとPostmanによってフェッチされたJSONを検証していることを認識しました。どうやらある種の前処理を行っているようです。URLをcurlingすると、大量の混乱が生じますそれは間違いなくJSONではありません。実際に混乱しているデータ型は何か、具体的に要求しているのにJSONを取得できないのはなぜかという疑問が残ります。

7
dangerismycat

Api.511.orgが有効なapi_keyを提供するAPI呼び出しにgzipを適用しているようです。また、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);
});
11
Rocky Sims