【问题标题】:How to handle HTTP code 4xx responses in fetch api如何在 fetch api 中处理 HTTP 代码 4xx 响应
【发布时间】:2017-03-07 23:46:26
【问题描述】:

我想知道当我们使用 ajax 函数时我们应该如何处理来自后端的 400。我们可以在 promise resolve 函数中创建 if 语句并检查 res 状态是否为 400。不同的方法是为 fetch 提供包装服务,当我们从服务器获得 400 时,我们会抛出异常。如何处理这个问题?

【问题讨论】:

  • 400?一个适当的解决方法可能是重新设计一种全新的方式来获取数据。也许用参数发出 1 个请求,并让 API 将所有数据拼凑在一起。
  • @CoreyOgburn 我相信 OP 的意思是 4xx HTTP 错误代码。
  • @TomG 这更有意义。
  • 是的,我的意思是400错误代码,例如有人登录时密码无效
  • 实际上,@ArturKasperek,我认为无效密码会正确抛出 409 冲突状态:服务器能够处理该请求,但发现存在与资源相关的问题(即用户)。

标签: javascript promise fetch


【解决方案1】:

将它合并到您的 HTTP 抽象中可能是一个好主意。也许有某种options 论点:

const myFetch = (method, path, {headers, strictErrors, whatever}) => {
  // fetch here, if strictErrors is true, reject on error.
  // return a Promise.
}

myFetch('GET', 'somepath', {strictErrors: true})
  .then(response => {})
  .catch(err => { /* maybe 400 */ });

fetch 的包装器通常是一个好主意,fetch 是一个相对较低级别的函数。就像在任何地方直接创建新的 XHR 对象不是一个好主意一样,我相信在应用程序的各个部分直接调用 fetch() 也不是一个好主意。在某些方面,它类似于全局变量。

【讨论】:

    【解决方案2】:

    我建议使用检查 response.ok 的包装器,如果响应代码为 2xx,则该包装器为真。

    请注意MDN page on fetch()中的此声明:

    对成功的 fetch() 的准确检查包括检查 承诺已解决,然后检查 Response.ok 属性是否已 值为真。 404的HTTP状态不构成网络 错误。

    这是一个这样的包装器:

    function fetchData() {
        return fetch.apply(null, arguments).then(response => {
             if (!response.ok) {
                 // create error object and reject if not a 2xx response code
                 let err = new Error("HTTP status code: " + response.status)
                 err.response = response
                 err.status = response.status
                 throw err
             }
             return response
        })
    }
    

    【讨论】:

      【解决方案3】:

      这样我们可以相应地处理所有类型的状态。

      fetch(url, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify({ user_email: email }),
      }).then((response) => {
        return new Promise((resolve) => response.json()
          .then((json) => resolve({
            status: response.status,
            ok: response.ok,
            json,
          })));
      }).then(({ status, json, ok }) => {
        const message = json.message;
        let color = 'black';
        switch (status) {
          case 400:
            color = 'red';
            break;
          case 201:
          case 200:
            color = 'grey';
            break;
          case 500:
          default:
            handleUnexpected({ status, json, ok });
        }
      })
      

      inspiration

      【讨论】:

        【解决方案4】:

        我为此找到的最佳方法是将其包装在一个新的 Promise 中,如果 response.ok 为 false,则拒绝带有错误上下文的 Promise。

        /**
         * Parses the JSON returned by a network request
         *
         * @param  {object} response A response from a network request
         *
         * @return {object}          The parsed JSON, status from the response
         */
        function parseJSON(response) {
          return new Promise((resolve) => response.json()
            .then((json) => resolve({
              status: response.status,
              ok: response.ok,
              json,
            })));
        }
        
        /**
         * Requests a URL, returning a promise
         *
         * @param  {string} url       The URL we want to request
         * @param  {object} [options] The options we want to pass to "fetch"
         *
         * @return {Promise}           The request promise
         */
        export default function request(url, options) {
          return new Promise((resolve, reject) => {
            fetch(endpoint  + url, options)
              .then(parseJSON)
              .then((response) => {
                if (response.ok) {
                  return resolve(response.json);
                }
                // extract the error from the server's json
                return reject(response.json.meta.error);
              })
              .catch((error) => reject({
                networkError: error.message,
              }));
          });
        }
        

        (对https://github.com/github/fetch/issues/203的最高评论)

        【讨论】:

          猜你喜欢
          • 2017-01-16
          • 2012-10-02
          • 2017-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-13
          • 1970-01-01
          相关资源
          最近更新 更多