当接口请求遇到 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/)或者刷题小程序(前端面试题宝典)的同学,如果近期准备或者正在找工作,千万不要错过,题库主打无广告和更新快哦~。

相关推荐
大圣编程1 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang1 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆2 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜3 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
负责的蛋挞4 小时前
异步HttpModule的实现方式
java·服务器·前端
丹宇码农6 小时前
把 HLS 字幕玩出花:zwPlayer 如何让 M3U8 视频支持全文搜索、翻译与码率自适应
前端·javascript·音视频·hls·视频播放器
2501_943782357 小时前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统
GV191rLvq7 小时前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net
吠品7 小时前
LangChain 里 tool_call_id 为空?一次 MCP 工具集成的排查记录
前端