繁体   English   中英

在节点服务器和前端中处理JSON响应

[英]Processing JSON response in node server and front end

我有一个正在发送JSON响应的节点服务器,但是为什么我必须在前端再次执行res.json()才能使响应正常工作?

另外,在前端处理获取的理想约定是什么? 像我应该如何构造我的异步/等待功能?

server.js

const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const fetch = require('node-fetch')

const app = express()
const port = process.env.PORT || 5000

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

const TRANSLINK_TOKEN = 'j2bXKzENILvyoxlZ399I'
const TRANSLINK_URL = 'http://api.translink.ca/rttiapi/v1/buses?apikey='

// API routes
app.get('/buses/location', async (req, res) => {
  const apiURL = `${TRANSLINK_URL}${TRANSLINK_TOKEN}`
  try {
    const response = await fetch(apiURL, { headers: { 'Accept': 'application/json' }})
    const jsonResponse = await response.json()
    res.send(jsonResponse)
  }
  catch (e){
    console.log(e)
  }
})

app.listen(port, () => console.log(`Listening on port ${port}`))

App.js

  fetchLocation = async () => {
    let locationURL = "/buses/location"
    fetch(locationURL)
      .then(res => {
        if (res.ok) {
          res.json()
          .then( (result) => {
            this.setState({
              active_vehicles: result
            })
          })
        }
      })
  }

这只是FE中如何实现fetch的本质。 它不会自动解析对json的响应。

请参阅: https//developer.mozilla.org/en-US/docs/Web/API/Body/json

您可以使用第三方库来为您处理内容类型(例如axios )-或者,如果您确信从服务器返回的所有内容都将是有效的json ,则可以编写一个包装fetch的简单函数。

顺便说一句,因为您已经在使用async您应该使用await而不是then / catch

  fetchLocation = async () => {
    try {
    let locationURL = "/buses/location"
    const response = await fetch(locationURL);
      if (response.ok) {
        const result = await response.json();
        this.setState({ active_vehicles: result });
      } else {
        // you probably should handle cases when response is not ok - fetch doesn't throw errors for 4xx, 5xx, 3xx codes.
      }
    } catch(e) {
      // handle request failure here.
    }
  }

您必须执行res.json,因为HTTP响应的主体只是一个字符串。 除非您告诉字符串,否则代码没有办法知道字符串的格式,这就是res.json的来源:您是在告诉代码将字符串响应解析为JSON并返回结果对象。

至于结构,如果您已经在前端使用了异步功能,则也应该在该处使用await来简化代码:

fetchLocation = async () => {
   let locationURL = "/buses/location";
   const res = await fetch(locationURL);
   if (res.ok) {
     const result = await res.json();
     this.setState({
       active_vehicles: result
      });
    }
  };

使用fetch ,每次发出HTTP请求时都需要使用res.json()

您的服务器正在向api.translink.ca发出GET请求。 调用res.json() ,它将处理在系统较低层中调用的异步任务,以实际接收和读取数据。

您的客户端也在发出GET请求,但不是向api.translink.ca发出该请求, api.translink.ca将其发送到您的主机。 如果您在自己的计算机上运行服务器,则该服务器将为localhost ,而完整的URL为localhost/buses/location 您正在发出另一个GET请求的事实就是为什么您需要再次调用res.json()

关于第二个问题,约定是优先事项。

await只是一种语法糖,可以避免所谓的回调地狱

只需将您从诺言获得的最终值解析为您期望的变量,并尽力使代码保持可读性和整洁性即可。

例如

更新代码:

fetchLocation = async () => {
  let locationURL = "/buses/location"
  let res = await fetch(locationURL);

  if (res.ok) {
    let result = await res.json();
    this.setState({ active_vehicles: result });
  }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM