首页 > 解决方案 > 如何处理来自服务器的空 json 响应

问题描述

我的前端应用程序中有一个函数调用我的 node.js 后端服务器:

客户端功能:

  this.geocode = (placeName) => {
    const url = '/api/twitter/geocode?' + 'query=' + encodeURIComponent(placeName);
    return fetch(url)
      .then(processResponse)
      .catch(handleError)
  }


  // API Helper methods
  const processResponse = function (response) {
    if (response.ok) {
      console.log(response);
      return response.json()
    }
    throw response;
  }

  const handleError = function (error) {
    if (error.json) {
      error.json().then(error => {
        console.error('API Error:', error.message || error)
      })
    } else {
      console.error('API Error:', error.message || error)
    }
  }

服务器路由:

app.get('/api/twitter/geocode', (req, res) => {
  var parameters = {
    query: req.query.query
  }

  Twitter.get('geo/search', parameters)
    .then(response => {
      console.log("RESPONSE:")
      console.log(response);
      // check if there is a place for the given query
      if(response.date.places.length > 0){
       res.send(response.data.result.places[0].bounding_box.coordinates[0][0]);
      }
      res.send()
    })
    .catch(e => res.status(500).send('Something broke!')
    )
});

placeName一个不存在的地方的名称(或至少 Twitter 不知道)时,就会出现问题。后端中的console.log(response)向我显示,对 Twitter api 的此类请求会导致返回消息没有地点数据:

 { data: 
    { result: { places: [] },
      query: 
       { url: 'https://api.twitter.com/1.1/geo/search.json?query=FOOBARTOWN',
         type: 'search',
         params: [Object] } },
   resp: 

/*etc...*/

如您所见,places是一个空列表。此响应导致我的前端崩溃。我想知道为什么。查看错误信息:

   const handleError = function (error) {
     if (error.json) {
  >     error.json().then(error => {
         console.error('API Error:', error.message || error)
       })
     } else {

以及浏览器中的其他一些控制台输出:

GET http://localhost:3000/api/twitter/geocode?query=FOOBARTOWN 500 (Internal Server Error) (model.js:197)
Uncaught (in promise) SyntaxError: Unexpected token S in JSON at position 0
    at handleError (model.js:214)

似乎我们正在获得error 500. 但为什么?我的服务器没有失败。node.js 控制台中没有错误消息。

此外,程序似乎以 . 结尾handleError,然后无法将错误转换为 json。

  1. 为什么会出现handleError?有什么错误?
  2. 为什么它说我的服务器出现故障(错误 500)?
  3. 我如何确保如果this.geocode收到一条空消息,我不会崩溃,并返回该空消息(这样我就可以检查空消息并在我的 React.js 组件中采取适当的行动)?

标签: javascriptnode.js

解决方案


为什么会出现handleError?有什么错误?

您的服务器正在发送一个 500 状态代码,Something broke!作为响应正文。

当您尝试res.json()在非 JSON 字符串上使用时,您会得到:

Uncaught SyntaxError: Unexpected token S in JSON at position 0

这条线if(error.json)没有做你认为它做的事情。 handleError当为 false 时被调用response.ok,因为否则您将抛出 fetch 响应对象,在这种情况下,error参数将是实现Body的 fetch 响应,它有一个json方法,即使 body 不是 JSON,这是您的情况.

handleError可以这样写,您将在其中处理fetch错误和非 2xx 响应。

const handleError = async function(error) {

  if(error instanceof Response) {

    if(error.headers.get('content-type').includes('application/json'))
      error = await error.json();
    else error = await error.text();

  }

  console.error('API Error:', error.message || error)
}

为什么它说我的服务器出现故障(错误 500)?

放一个console.log(e)Twitter.get().catch你会发现。


Twitter.get().then也错了,因为您要发送两次响应。

if(response.date.places.length > 0){
       res.send(response.data.result.places[0].bounding_box.coordinates[0][0]);
}
res.send()

应该:

 if(response.date.places.length > 0)
   return res.send(response/*...*/);

 res.send()

推荐阅读