使用 fetch 检查内容

Checking for content using fetch

我正在使用 fetch 进行 API 调用,其中 return JSON 数据。

有时 API 调用 return 内容的状态 OKnull。我依靠检查状态来获取内容,但这给了我一个错误,因为没有 JSON 数据。

我得到的错误是:Uncaught (in promise) SyntaxError: Unexpected end of JSON input

这是我的典型抓取模式,显然我需要通过为 JSON 数据再添加一次检查来改进它。我该如何修改?

export const getSomeData = () => {

    return (dispatch) => fetch('/api/myapifunction', fetchOptionsGet())
        .then((response) => {
            if(response.ok) {
                // I need to add logic here to check for JSON data before calling parseJSON
                parseJSON(response)
                .then(data => {
                    // Do something
                })
            } else {
                // Failed
                // Handle failure
            }
        })
}

我为 fetchOptions 创建了函数,例如 GET 或 POST 以及 parseJSON。它们是简单的函数。这是 parseJSON 的样子:

export const parseJSON = (response) => {
    return response.json();
}

据我了解,response.json()只是一个承诺,不一定是数据。如何检查我是否收到任何 JSON 数据?

如果浏览器能够将响应内容解析为有效 json,response.json() 承诺将 运行 正确并进入 .then 部分。

如果无法这样做 - 您可以使用 .catch 查看问题所在:

parseJSON(response)
    .then(json => {
        // Do something with the json data
    }).catch( reason => {
        // response is not a valid json string
    })

这里的技巧是您的服务有点口是心非。它说它是 OK,但随后根本不发送任何字节。 JSON.parse('') 抛出同样的错误。

您可以按照 Dekel 的说明使用 catch 解决此问题,或者您可以使用 response.text():

if (response.ok) {
  response.text()
    .then(text => text && text.length ? response.json() : Promise.resolve({}))
    .then(data => { // here you'll need to handle an empty object

这基本上是检查返回内容的字符串值。如果没有返回任何内容,它会给你一个空对象而不是抛出错误。这将有助于区分由于数据错误导致的 JSON 解析错误和根本没有数据。