如何处理fetch API中的HTTP代码4xx响应

发布于 2025-02-09 07:31:47 字数 128 浏览 1 评论 0原文

我想知道当使用Ajax功能时,如何从后端处理400。我们可以在Promise Resolve功能中进行IF IF语句,并检查RES状态是否为400。不同的方法正在为获取包装服务,而当我们从服务器获得400时,我们会抛出异常。如何解决这个问题?

I was wondering how we should handle 400 from backend when we use ajax function. We can make if statement in promise resolve function and check if res status is 400. Different approach is making wrapper service for fetch, and when we got 400 from server we throw exception. How to deal with that problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北渚 2025-02-16 07:31:47

我建议一个检查Response.ok的包装器,如果响应代码为2xx,则将是正确的。

请注意此语句来自

准确检查成功的Fetch()将包括检查是否检查
承诺解决了,然后检查响应属性是否具有
真实的价值。 HTTP状态为404不构成网络
错误。

这是这样的包装器:

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
    })
}

I'd suggest a wrapper that checks response.ok which will be true if the response code is 2xx.

Note this statement from the MDN page on fetch():

An accurate check for a successful fetch() would include checking that
the promise resolved, then checking that the Response.ok property has
a value of true. An HTTP status of 404 does not constitute a network
error.

Here is a wrapper like this:

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
    })
}
冷情 2025-02-16 07:31:47

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

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

This way we can handle all types of status accordingly.

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

情定在深秋 2025-02-16 07:31:47

将其纳入您的HTTP抽象可能是一个好主意。也许有了某种选项参数:

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是一个相对较低的级别函数。就像直接在各处创建新的XHR对象并不是一个好主意一样,我相信在应用程序的各个部分中直接调用fetch()并不是一个好主意。在某些方面,它类似于全局变量。

Incorporating it into your HTTP abstraction is probably a good idea. Perhaps with some sort of options argument:

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 */ });

A wrapper around fetch is generally a good idea, fetch is a relatively low level function. Just as it isn't a good idea to directly create new XHR objects everywhere, I believe it isn't a good idea to directly call fetch() in various parts of your application. It's akin to a global variable, in some ways.

凉宸 2025-02-16 07:31:47

我发现的最佳方法是将其包裹在一个新的承诺中,如果Response.ok是错误的,请在错误上下文中拒绝承诺。

/**
 * 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.com/github/fetch/sissues/203

The best approach I've found for this is to wrap it in a new Promise, and if response.ok is false, reject the Promise with the error context.

/**
 * 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,
      }));
  });
}

(Top comment on https://github.com/github/fetch/issues/203)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文