简体   繁体   English

拒绝获取承诺:访问回复文本

[英]Rejected Fetch Promise: access to response text

I'm using the Fetch API to load some JSON. 我正在使用Fetch API加载一些JSON。 Therefore, I use .json() on the response stream and also the optional second function argument ( onRejected ) in .then() , which has only one argument, the rejection reason. 因此,我使用.json()上响应流,并且还可选的第二函数参数( onRejected )中.then()它只有一个参数,该拒绝原因。

If something goes wrong (like the response being no valid JSON), I want access to the raw response text to have some meaningful error log or to further process the unexpected response. 如果出现问题(例如响应不是有效的JSON),我希望访问原始响应文本以获取有意义的错误日志或进一步处理意外的响应。

Consider this simplified snippet: 请考虑以下简化代码段:

fetch('api.php')
.then(
    response => { return response.json(); }
)
.then(
    json => { /* useful fulfillment value, a JSON object */ },
    reason => { /* string message only */ }
);

If the API responds with something other than valid JSON, it will reject with the following reason: 如果API响应时使用的不是有效JSON,则它会由于以下原因而拒绝:

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data SyntaxError:JSON.parse:JSON数据的第1行第1列出现意外字符

While this is a perfectly clear error message, it lacks a dump of what actually caused the error. 尽管这是一条非常清晰的错误消息,但它缺少真正导致错误的原因的转储。

I considered using .text() and then trying to parse the JSON myself, but that would somewhat contravene the purpose of .json() . 我考虑过使用.text() ,然后尝试自己解析JSON,但这在某种程度上违背.json()的目的。

Is there a reasonable way to access the response text if stream-reading is rejected? 如果流读取被拒绝,是否有合理的方法来访问响应文本?

You can check the content type: 您可以检查内容类型:

  var contentType = response.headers.get("content-type");
  if(contentType && contentType.indexOf("application/json") !== -1) {
       response => { return response.json(); }
  }
  else{
       response => { return response.text(); }
  }

If you want to get the response in the rejection callback you can do something like this 如果要在拒绝回调中获取响应,可以执行以下操作

  response => { 
          var text = '';
          try{
              text= response.json(); 
          }
          catch (e if e instanceof SyntaxError) {
             text = response.text();
          } 
          return text;
  }

Lets say this is nasty but could solve the problem: 可以说这很讨厌,但可以解决问题:

let res;
fetch('api.php')
.then(
    response => { res = response; return response.json(); }
)
.then(
    json => { /* useful fulfillment value, a JSON object */ },
    reason => { /* use res variable */ }
);

If the response is certain to have a body then read the text using the response.text() method (as shown in other answers or elsewhere: MDN , Google Web ) then parse it yourself before or after any additional conditions or checks (is it JSON? check then use JSON.parse). 如果响应肯定具有主体,则使用response.text()方法(如其他答案或其他地方所示: MDNGoogle Web )读取文本,然后在任何其他条件或检查之前或之后自行解析(是否JSON?检查然后使用JSON.parse)。

Using the body is not an effective technique for generally handling errors. 使用身体不是通常用于处理错误的有效技术。 What happens in cases where the API doesn't include a body, or it's malformed, or the request fails entirely? 如果API不包含正文,格式错误或请求完全失败,会发生什么情况? Instead look at the response.statusText (eg 'Not found.'), response.status (eg 404) and other headers. 而是查看response.statusText (例如“未找到”), response.status (例如404)和其他标头。 Or in cases where the fetch fails the response will be an Error object with an error.message and error.stack . 否则,在获取失败的情况下,响应将是带有error.messageerror.stackError对象。 If you own the API and require more sophisticated/predictable messaging consider adding custom headers like 'special-message' and retrieve it with something like if(response.headers) response.headers.get('special-message') . 如果您拥有API并需要更复杂/可预测的消息传递,请考虑添加自定义标头(例如'special-message'),并使用if(response.headers) response.headers.get('special-message')类的内容进行检索。

Only work with the body once these other scenarios are not an issue to have a little more predictability. 只有在这些其他场景不再具有可预测性的问题时,才可以与身体合作。 The above headers are also available before any streaming complete to further simplify and improve responsiveness and response handling. 在任何流式传输完成之前,上述标头也可用,以进一步简化和改善响应性和响应处理。

暂无
暂无

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

相关问题 Axios:如何访问被拒绝承诺的响应对象? - Axios: How to access the response object, of a rejected promise? 拒绝 Promise 但 response.ok 是真的。 JavaScript Rails 获取请求“无法在'响应'上执行'json':正文 stream 已读取” - Rejected Promise but response.ok is true. JavaScript Rails fetch request “Failed to execute 'json' on 'Response': body stream already read” 在Promise.all()中自定义被拒绝的响应 - Customize rejected response in Promise.all() fetch => response.json()请求被拒绝 - fetch => response.json() request being rejected 使用reactjs和Nodejs中的fetch API在POST登录中拒绝承诺 - Promise rejected in POST login using fetch API in reactjs and Nodejs 开玩笑 - 如何测试返回被拒绝的 Promise 的 Fetch() 调用? - Jest - How To Test a Fetch() Call That Returns A Rejected Promise? 使用 Promise.allSettled 捕获被拒绝的 Promise 的请求响应代码 - Capture request response code of rejected promises with Promise.allSettled “ [url]”的FetchEvent导致网络错误响应:承诺被拒绝 - FetchEvent for “[url]” resulted in a network error response: the promise was rejected AngularJS Promise被拒绝,无需等待异步响应(它应该解决) - AngularJS Promise being rejected without waiting for async response (it should resolve) 如何使用 Promise.allSettled 访问 fetch/http 调用的响应值? - How do I access the response value for a fetch/http call using Promise.allSettled?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM