Не удается проанализировать ответ API в узле JS — ответ выглядит как массив

avatar
Betilla
8 августа 2021 в 16:18
159
1
1

Я новичок в этом, я пытался посмотреть другие сообщения, но не могу найти правильный ответ. Я использую Node JS https для вызова API для получения информации о состоянии общественного транспорта. Ответ выглядит как массив объектов, но я не могу его правильно проанализировать.

Это мой код:

//app set up
const express = require("express");
const https = require("https");
const bodyParser = require("body-parser");
const dotenv = require("dotenv").config();
const ejs = require("ejs");

const app = express();

app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended:true}));



 // get request to the page
app.get("/status", function(req,res){
    // get request to the API
 const url="https://api.tfl.gov.uk/Line/victoria/Status?app_id="+process.env.PRIMARY_KEY+"&app_key="+process.env.SECONDARY_KEY;
    
https.get(url, function(response){
        console.log (response);
        console.log(response.statusCode);
        console.log(response.headers);
        let responseBody = "";
        let parsedBody = [];
        response.setEncoding("utf-8");
        response.on("data", function(chunk){
            responseBody += chunk;
            console.log("this is the body response"+responseBody);
            console.log("this is the body response lenght"+responseBody.length);
            console.log("this is the body position 0 "+responseBody[0]);
            console.log("this is the body position 1 "+responseBody[1]);
        });     
        res.redirect("/");
});

Заголовок возвращает следующее:

    {
  date: 'Sun, 08 Aug 2021 11:37:41 GMT',
  'content-type': 'application/json; charset=utf-8',
  'transfer-encoding': 'chunked',
  connection: 'close',
  'cache-control': 'public, must-revalidate, max-age=30, s-maxage=60',
  via: '1.1 varnish',
  age: '0',
  'access-control-allow-headers': 'Content-Type',
  'access-control-allow-methods': 'GET,POST,PUT,DELETE,OPTIONS',
  'access-control-allow-origin': '*',
  'api-entity-payload': 'Line,LineStatus',
  'x-backend': 'api',
  'x-cache': 'MISS',
  'x-cacheable': 'Yes. Cacheable',
  'x-frame-options': 'deny',
  'x-proxy-connection': 'unset',
  'x-ttl': '60.000',
  'x-ttl-rule': '0',
  'x-varnish': '935110596',
  'x-aspnet-version': '4.0.30319',
  'x-operation': 'Line_StatusByIdsByPathIdsQueryDetail',
  'x-api': 'Line',
  'cf-cache-status': 'DYNAMIC',
  'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
  server: 'cloudflare',
  'cf-ray': '67b874417d2b078e-LHR'
}

похоже, что ответ представляет собой файл JSON -- верно?

Тело ответа выглядит следующим образом:

[{"$type":"Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities","id":"victoria","name":"Victoria","modeName":"tube","disruptions":[],"created":"2021-08-05T16:15:46.917Z","modified":"2021-08-05T16:15:46.917Z","lineStatuses":[{"$type":"Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities","id":0,"statusSeverity":10,"statusSeverityDescription":"Good Service","created":"0001-01-01T00:00:00","validityPeriods":[]}],"routeSections":[],"serviceTypes":[{"$type":"Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities","name":"Regular","uri":"/Line/Route?ids=Victoria&serviceTypes=Regular"},{"$type":"Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities","name":"Night","uri":"/Line/Route?ids=Victoria&serviceTypes=Night"}],"crowding":{"$type":"Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities"}}]

И если я предполагаю, что это массив объектов и записываю его длину и элементы, я получаю следующее:

responseBody.length= 900
responseBody[0] = [
responseBody[1] = {

Если я использую responseBody += JSON.parse(chunk), я получаю сообщение об ошибке:

undefined:1
[{"$type":"Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities","id":"victoria","name":"Victoria","modeName":"tube","disruptions":[],"created":"2021-08-05T16:15:46.917Z","modified":"2021-08-05T16:15:46.917Z","lineStatuses":[{"$type":"Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities","id":0,"statusSeverity":10,"statusSeverityDescription":"Good Service","created":"0001-01-01T00:00:00","validityPeriods":[]}],"routeSections":[],"serviceTypes":[{"$type":"Tfl.Api.Presentation.Entities
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at IncomingMessage.<anonymous> (C:\Users\THIS IS MY PATH\index.js:44:34)
    at IncomingMessage.emit (events.js:315:20)
    at IncomingMessage.Readable.read (internal/streams/readable.js:519:10)
    at flow (internal/streams/readable.js:992:34)
    at resume_ (internal/streams/readable.js:973:3)
    at processTicksAndRejections (internal/process/task_queues.js:80:21)

И если я использую responseBody += JSON.parse(JSON.stringify(chunk)) я снова получаю это

 responseBody.length= 900
    responseBody[0] = [
    responseBody[1] = {

Есть предложения? Я получаю ответ в формате, отличном от JSON, поэтому я должен преобразовать его по-другому? или что-то не так с моим кодом? спасибо

Источник

Ответы (1)

avatar
eol
8 августа 2021 в 16:30
0

В обратном вызове on("data") вы получаете фрагменты данных, поэтому использовать JSON.parse имеет смысл только после того, как все фрагменты собраны. Итак, вы должны сделать что-то вроде этого:

response.on("data", (chunk) => {
  responseBody += chunk;           
});  

response.on("end", () => {
  const parsedJson = JSON.parse(responseBody);
  console.log(parsedJson);
}); 

В качестве примечания: существует множество библиотек, которые вы можете использовать для http-запросов, которые делают такие вещи из коробки, например. https://www.npmjs.com/package/node-fetch#json чтобы назвать один.