简体   繁体   English

如何使用 fetch 处理响应 .json 和 .text?

[英]How to handle response .json and .text using fetch?

I'm fetching an API that returns a json but when it has an error, it returns only a text (In node with express, results are returned with .json({}) and errors with .send('string') ), but I can't modify the API我正在获取一个返回 json 的 API,但是当它出现错误时,它只返回一个文本(在带有 express 的节点中,结果以.send('string') .json({})返回,错误以.send('string') ),但我无法修改 API

So I'm trying to make something that reads the json, but if it's an text, it will go in .catch where the error is the text.所以我试图做一些读取 json 的东西,但如果它是一个文本,它会进入.catch ,其中错误是文本。

Here is what I have tried but with no success.这是我尝试过但没有成功的方法。

fetch(apiUrl)
    .then(res => {
        try {
            let json = res.json()
            return json
        } catch (error) {
            return new Promise((resolve, reject) => reject(res.text()))
        }
    })
    .then(res => {
        // get result from res.json() **res == res.json**
    })
    .catch(error => {
        // get result from res.text() **res == res.text**
    })

How can I achieve this?我怎样才能做到这一点? How to get res.json() in the next .then() but if it fails, get res.text() in the .catch ?如何获得res.json()在未来.then()但如果失败,得到res.text().catch

Edit:编辑:

I want to get the .text in .catch .我想在.catch获取.text I don't know why, but throwing res.text() doesn't work.我不知道为什么,但是抛出res.text()不起作用。

Ideally, your client application should know what response kind to expect and have static code that calls the appropriate method.理想情况下,您的客户端应用程序应该知道预期的响应类型并具有调用适当方法的静态代码。


Another way to deal with your situation is to inspect the response contentType and call .json() or .text() depending on particular response header value.处理您的情况的另一种方法是检查响应contentType并根据特定的响应标头值调用.json().text()

handleResponseStatusAndContentType(response) {
  const contentType = response.headers.get('content-type')!;

  if (response.status === 401) throw new Error('Request was not authorized.');

  if (contentType === null) return Promise.resolve(null);
  else if (contentType.startsWith('application/json;')) return response.json();
  else if (contentType.startsWith('text/plain;')) return response.text();
  else throw new Error(`Unsupported response content-type: ${contentType}`);
}

Usage:用法:

return fetch(
  url,
  requestInit,
)
.then(response => handleResponseStatusAndContentType(response))
.catch(error => {
  console.error(error);
  return error;
});

Another approach would be to simply format eveyrthing to text initially and only then try to parse it, while throwing an error in case of parsing issues.另一种方法是最初将所有内容格式化为文本,然后才尝试解析它,同时在解析问题的情况下抛出错误。

 fetch("http://maps.googleapis.com/maps/api/geocode/json?address=google") .then(res => res.text()) .then(body => { try { return JSON.parse(body); } catch { throw Error(body); } }) .then(console.log) .catch(console.error); fetch("http://maps.googleapis.com/maps/api/geocode/xml?address=google") .then(res => res.text()) .then(body => { try { return JSON.parse(body); } catch { throw Error(body); } }) .then(console.log) .catch(console.error);

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

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