2016-12-03 5 views
4

Я уже несколько часов разрываю волосы на этом месте.«Неожиданный токен в JSON в позиции 0» с использованием JSON.parse в узле с действующим JSON

У меня есть простой сервер узла, который обращается к внешнему API, чтобы получить (массивный, как 4+ МБ) бит JSON. Я использую примерно как шаблонный запрос, как вы можете получить, взятый прямо из узла документации:

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. (Обратите внимание на два пробела между «токеном» и «в».)

Я проверил 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.stringify ИНГОМ первым, toString ING, преобразовывая в new Buffer, а затем stringifying, .trim ИНГ белого пространства, и replace ИНГ всех видов уцелевших героев, все безрезультатно.

Что мне здесь не хватает?


EDIT: я понял, что я проверки JSON извлекалось Chrome и Почтальон, который, по-видимому делают некоторые предварительной обработки какой-то. curl В URL-адресе появляется целая путаница, которая, безусловно, не JSON. Все еще остались вопросы о том, какой тип данных это беспорядок на самом деле, и почему я не получаю JSON, когда я специально его запрашиваю.

+0

1fef персонаж писать RAWDATA в файл является utf8 кодом для кавычки characer ('), который заставляет меня думать JSON.parse() задыхается от этого. –

+0

Что сказать, если вы console.log (rawData); на линии до const parsedData = JSON.parse (rawData); –

+1

@RockySims Вход в систему дает целую кучу gobbledygook, который определенно не JSON: ' ε @ + @} < ot Xu y ֙ % Msgstr " $ 'н.д. $ XFI% 1t! FO @)> ܪ ZZ7q30uV 衷 ZrR34> * J < ͏ 2o & m R : | p > [= x} m { 1 E 4OQ + rjZȏ @} ź6ҪGu [ڞ "妕 d | т>} + | г> J \ k O l IY d Ӓ = 0 vYTe] i ޝ # SQb 9-l 6} U [ ? d y & ' Я думаю, что я была сбита с толку некоторой автоматической предварительной обработкой t Хром/Почтальон делал. 'curl'ing URL-адрес дает такой же не-JSON беспорядок. Однако я не знаю, какой тип данных я получаю. – dangerismycat

ответ

9

Похоже, api.511.org применяет gzip для любых вызовов api, которые предоставляют действительную api_key. Также он возвращает недопустимый первый символ в ответе 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); 
}); 
+0

Ты СПАСИБО ЖИЗНИ! Огромное спасибо!! – dangerismycat

+0

Рад, что я мог помочь. О, и, пожалуйста, обязательно вернитесь к использованию своего собственного ключа api. Я забыл снять свой тестовый ключ api, прежде чем публиковать свой ответ. –

+0

Не волнуйтесь, я только что адаптировал ваш ответ и продолжал использовать свой собственный ключ API. Еще раз спасибо! – dangerismycat

Смежные вопросы