fetch 如何处理 302()

问题描述 fetch 发送一个请求,请求登录过期返回 302,浏览器自动重定向到 Response Headers 的 Location 登录页面。Location 对应的服务器不接受跨域请求,因此页面报错。
尝试在 fetch 的回调函数处理,一旦 fetch 的 response status 是 302 就跳转到 Location 页面, 但是不论在fetch的回调函数中做任何事情,都执行不到。
fetch 如何处理 302()
文章图片

什么是 HTTP 状态码 302 ? HTTP 302 重定向状态码表明请求的资源被暂时的移动到了由Location头部指定的 URL 上。浏览器会重定向到这个URL, 但是搜索引擎不会对该资源的链接进行更新。
使用场景:

  1. 在 OAuth 流程中,302 经常使用;
  2. 有时候请求的资源无法从其标准地址访问,但是却可以从另外的地方访问。在这种情况下可以使用临时重定向。
  3. 搜索引擎不会记录该新的、临时的链接。在创建、更新或者删除资源的时候,临时重定向也可以用于显示临时性的进度页面。
痛点:浏览器 自动 发起对 重定向地址的请求,js 无法插手干预。
fetch 为什么不能拦截302? 一般请求的流程:
  • fetch 发送请求;
  • 服务器返回 response 并且带有状态码(比如200) ;
  • 浏览器接收到响应,结果递交给fetch;
  • 从 fetch 的回调函数获取相应数据;
fetch 如何处理 302()
文章图片

302 临时重定向请求的流程是:
  • fetch 发送请求;
  • 服务器返回 response (带有location) 并且带有 302 状态码;
  • 浏览器接收到响应,自动从302响应的头信息的重定向地址中取到 location 进行跳转;
对于重定向,当浏览器检查到 headers 中存在 Location,会直接进行跳转,不会告知任何请求发送者(fetch),这时候发送者会以为请求还在处理中。所以此时的 fetch 的 then 和catch 都捕获不到信息
如何解决? 1. 配置 fetch 的 redirect
fetch 的 options 配置项redirect,用于配置可用的 redirect 模式。
redirect 的值有:
  • follow:默认, 自动重定向;
  • error:如果产生重定向将自动终止并且抛出一个错误;
  • manual:手动处理重定向;
error 如果产生重定向将自动终止并且抛出一个错误。此错误可以在 fetch catch 回调函数中捕获:TypeError: Failed to fetch
fetch 只有服务器错误才调用 catch,其他都会调用 then 函数,那么 302 为什么会调用catch?
不是 302 导致 catch 被调用而是重定向后的请求的 response 导致 catch 被调用。
fetch 如何处理 302()
文章图片

manual 手动处理重定向。通过这种方法只能知道发生了重定向,但是 response 的内容非常有限,无法获取到具体的信息。
fetch 如何处理 302()
文章图片

2. 后端改写状态码,前端手动处理 目前的 302 是对 404 的改写,那么如果我们将 404 改写成自定义状态码,然后前端捕获到这个状态码后,进行手动处理。这种方法则需要前后端的同学都做处理。
301 和 302 状态码区别 301:永久重定向。一旦请求发往某个URL,状态码返回301,那么浏览器就会自动跳转到 header中 Location 对应的 url。下次请求,再次向 location 对应的 url 发送请求。
  • 之后每次请求都会跳转到 location 对应的url。没有例外。
  • 浏览器可以缓存从这个 url 获取的响应。
【fetch 如何处理 302()】302:临时重定向。请求的资源临时从不同的url获取。一旦请求发往某个URL,状态码返回302,那么浏览器就会自动跳转到 header中 Location对应的 url。但是下次再次请求的时候向原来的url发请求。
  • 每次请求不能确定是否向 Location 的 url 发请求,因此需要先想原来的 url 发送请求确定。
  • 浏览器不可缓存从重定向的 url 获取到的响应。

    推荐阅读