- 读完本文大约需要5分钟
- 本文前置知识:HTTP状态码、fetch
- 阅读难度:初级
- 本文关键代码及输出结果都写了出来,可以不用编译器编译,直接浏览文章
事情发生在昨天,在调用接口的时候,接口写错了:
/xxx/interventionlist
写成了 /xxx/Interventionlist
果不其然红一片,点开network后,找到调用的接口 ⬇️
这里的302是对404处理后的结果,将所有出现404的结果跳转到一个指定的404页面。 不过这种跳转应该发生在访问页面时,而不是在调用接口传参交互时。
因此我决定对这种出现302的错误进行一个封装,在亲自踩过坑后,这篇文章诞生了!
重定向时无法直接捕获状态码
最开始我尝试直接做个 checkStatus()
来处理这种问题,当response.status === 302
时console.log
出来
...
function checkStatus(response) {
console.log(response) // 注1
// 尝试对302的捕获
if (response.status === 302) {
console.log(response) // 注2
}
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
}
...
// url为调用的接口地址,options为fetch的配置
fetch(url, options)
.then(checkStatus)
.then(...)
结果啥都没输出,注1、注2的console.log
都没有输出内容
我们梳理一下请求的流程
fetch 发送请求 -->
服务器返回 response 并且带有状态码(比如200) -->
浏览器接收到响应,结果递交给fetch -->
我们从fetch的回调函数获取相应数据 ✅
而 重定向 时的过程应该这样:
fetch 发送请求 -->
服务器返回 response(带有location) 并且带有状态码302 -->
浏览器接收到响应,通过location进行跳转 -->
服务器返回 response 并且带有状态码(比如200) -->
...
这就是为什么我们拿不到response的原因
那么结论一目了然:
重定向时无法直接捕获状态码
解决方案
方案A: fetch配置redirect
fetch的options配置里有一条叫做redirect
redirect:
- follow 默认,跟随跳转
- error 阻止并抛出异常
- manual 阻止重定向 (并不是像它的名字描述的那样「手动」)
error
fetch('/xxx/Interventionlist', { redirect: 'error' })
.catch(reason => {
console.error(reason);
});
在出现重定向时,我们会获得一个额外的信息 ⬇️
manual
fetch('/xxx/Interventionlist', { redirect: 'manual' })
.then(reason => {
console.log(reason);
});
设置manual后不会抛出异常,但会获取到一个被过滤过后的response,里面几乎所有内容都被过滤掉了。
拿到这个响应只能知道这是一个重定向,无法得到其它任何有用的信息 ⬇️
通过这种方法只能知道发生了重定向,但是无法获取到具体的信息。
但是我们已经能判断发生了重定向,并且输出自己需要的东西方便排错
我并不知道这是出于什么安全因素考虑的会过滤掉 response 中的信息,如果有了解的希望能在评论里探讨一下
这种方式目前是我所知的唯一 纯前端 能判断发生重定向的方法
方案B: 后端改写状态码,前端手动处理
目前的302是对404的改写,那么如果我们将404改写成自定义状态码,然后前端捕获到这个状态码后,进行手动处理。
这种方法则需要前后端的同学都做处理。