如何在 fetch api 中处理 HTTP 代码 4xx 响应
Posted
技术标签:
【中文标题】如何在 fetch api 中处理 HTTP 代码 4xx 响应【英文标题】:How to handle HTTP code 4xx responses in fetch api 【发布时间】: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 冲突状态:服务器能够处理该请求,但发现存在与资源相关的问题(即用户)。
【参考方案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的最高评论)
【讨论】:
以上是关于如何在 fetch api 中处理 HTTP 代码 4xx 响应的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 中处理 fetch API AJAX 响应
如何使用 Redux Thunk 处理 fetch() 响应中的错误?