当接口请求遇到 302 状态码……

大家好,我是刘布斯。

前两天在面试一位同学的时候,聊到了 token 过期,需要重新登录的场景。

这位同学提到,当时后端对过期的 token 进行了拦截,接口会返回 302 状态码,前端就会进行重定向到登录页面。

我提出了质疑:接口返回302,浏览器会自动做重定向到登录页吗?

这位同学顿时愣住了,但短暂的思考后,坚定地回复:我们对网络请求做了封装,当监测到 302 的状态码,就会用 js 做重定向。

这位同学的回答确实有问题,今天我们就来聊聊,当接口请求遇到 302 的时候会发生什么。

302/303/307 状态码

状态码是常见的面试题,以 3xx 开头的常见状态码有:

  • 301:永久重定向。请求资源的 URL 已永久更改。在响应中给出了新的 URL。
  • 302:临时重定向。此响应代码表示所请求资源的 URI 已 暂时 更改。未来可能会对 URI 进行进一步的改变。因此,客户机应该在将来的请求中使用这个相同的 URI。
  • 303:临时重定向。重定向的方法会统一使用 GET 。
  • 304:内容未改变。用于浏览器的缓存,告诉客户端响应还没有被修改,因此客户端可以继续使用相同的缓存版本的响应。
  • 307 :也是临时重定向。与 302 有相同的语义,但用户代理不能更改所使用的 HTTP 方法:如果在第一个请求中使用了 POST,则在重定向的请求中也必须使用 POST

重定向,顾名思义,就是把请求重新指向了一个新的地址。

上面可以看到 302/303/307 这三个状态码的功能比较类似,将它们单独拎出来对比下差异:

状态码 状态文本 处理方法 典型应用场景
302 Found GET 方法不会发生变更。其他方法有可能会变更为 GET 方法。 由于不可预见的原因该页面暂不可用。
303 See Other GET 方法不会发生变更,其他方法会变更为 GET 方法(消息主体丢失)。 用于 PUT 或 POST 请求完成之后重定向,来防止由于页面刷新导致的操作的重复触发。
307 Temporary Redirect 方法和消息主体都不发生变化。 由于不可预见的原因该页面暂不可用。当站点支持非 GET 方法的链接或操作的时候,该状态码优于 302 状态码。

手动处理接口的重定向?

302 状态码有个问题:浏览器通常会自动发起对重定向地址的请求,js 无法插手干预

对于重定向,当浏览器检查到 headers 中存在 Location,会直接进行跳转,不会告知任何请求发送者(fetch),这时候发送者会以为请求还在处理中。所以此时的 fetch 的 then 和catch 都捕获不到信息

在使用 fetch 进行请求的时候,可以通过 redirect 参数配置如何处理重定向。

redirect可选的值有三个:

  • follow:自动重定向
  • error :如果产生重定向将自动终止并且抛出一个错误TypeError: Failed to fetch
  • manual:手动处理重定向

在 Chrome 中默认使用follow(Chrome 47之前的默认值是manual)。

大家是不是以为,我们可以设置成 manual 后,拿到 3xx 的状态码和重定向的地址,我们可以在 js 中自定义实现自定义的跳转?

其实并不是,manual 的准确意思并不是手动处理,而是让浏览器不做处理。通过这种方法只能知道发生了重定向,但是 response 的内容非常有限,无法获取到具体的信息(可以参考这个 issue:Cannot get next URL for redirect="manual")。

具体一点,如果我们设置成 manual时,如果发生了重定向,会拿到 typeopaqueredirect 的response:

json 复制代码
{
    "body": null,
    "bodyUsed": false,
    "headers": {},
    "ok": false,
    "redirected": false,
    "status": 0,
    "statusText": "",
    "type": "opaqueredirect",
    "url": "https://xxx.com",
}

另外提一句,manual 一般是配合 Service Worker 使用。

302 状态码的总结

当浏览器发起一个请求,服务端返回了302状态码,浏览器会根据响应头中的 location 字段,重新发起一个请求。当重定向次数过多的时候,浏览器会抛出 ERR_TOO_MANY_REDIRECT 的异常。

请求分两种情况:

  • 浏览器页面请求:跳转到新的页面。
  • ajax请求:返回最后重定向地址的响应。

面试的那位同学提到,服务端会在接口中返回302,然后由前端进行拦截,大概率是记错了。

如何处理未登录跳转的问题

那么问题来了,我们该如何处理未登录的问题呢?

比较常规的方案是后端返回 401 状态码,前端对接口请求进行封装,遇到 401 状态码就跳转到登录页面。

最后

还没有使用过我们刷题网站(fe.ecool.fun/)或者刷题小程序(前端面试题宝典)的同学,如果近期准备或者正在找工作,千万不要错过,题库主打无广告和更新快哦~。

相关推荐
倚肆9 分钟前
CSS 动画与变换属性详解
前端·css
blackorbird21 分钟前
谷歌 Chrome 浏览器的指纹识别技术,一边反追踪一边搞追踪
前端·chrome
Mintopia1 小时前
🚀 共绩算力:3分钟拥有自己的图像优化服务-CodeFormer:先进的图像算法优化、修复马赛克、提升图片清晰度等
前端·人工智能·ai编程
Lhuu(重开版1 小时前
html语法
前端·html
月弦笙音1 小时前
【vue3】这些不常用的API,却很实用
前端·vue.js·面试
小只笨笨狗~1 小时前
css-文字背景渐变色
前端·css·html
BingoGo1 小时前
CSS 也要支持 if 了 !!!CSS if() 函数来了!
前端·css
用户6600676685391 小时前
深入解析JavaScript数组:从内存原理到高效遍历实践
前端·javascript
有点笨的蛋1 小时前
CSS 定位彻底搞懂:五种 position 的真实差异与最佳实践
前端·css