共计 1520 个字符,预计需要花费 4 分钟才能阅读完成。
问题形容
fetch 发送一个申请,申请登录过期返回 302,浏览器主动重定向到 Response Headers 的 Location 登录页面。Location 对应的服务器不承受跨域申请,因而页面报错。
尝试在 fetch 的回调函数解决,一旦 fetch 的 response status 是 302 就跳转到 Location 页面,然而不管在 fetch 的回调函数中做任何事件,都执行不到。
什么是 HTTP 状态码 302?
HTTP 302 重定向状态码表明申请的资源被临时的挪动到了由 Location
头部指定的 URL 上。浏览器会重定向到这个 URL,然而搜索引擎不会对该资源的链接进行更新。
应用场景:
- 在 OAuth 流程中,302 常常应用;
- 有时候申请的资源无奈从其规范地址拜访,然而却能够从另外的中央拜访。在这种状况下能够应用长期重定向。
- 搜索引擎不会记录该新的、长期的链接。在创立、更新或者删除资源的时候,长期重定向也能够用于显示临时性的进度页面。
痛点:浏览器 主动 发动对 重定向地址的申请,js 无奈插手干涉。
fetch 为什么不能拦挡 302?
个别申请的流程:
- fetch 发送申请;
- 服务器返回 response 并且带有状态码(比方 200);
- 浏览器接管到响应,后果递交给 fetch;
- 从 fetch 的回调函数获取相应数据;
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 被调用。
manual
手动解决重定向。通过这种办法只能晓得产生了重定向,然而 response 的内容十分无限,无奈获取到具体的信息。
2. 后端改写状态码,前端手动解决
目前的 302 是对 404 的改写,那么如果咱们将 404 改写成自定义状态码,而后前端捕捉到这个状态码后,进行手动解决。这种办法则须要前后端的同学都做解决。
301 和 302 状态码区别
301:永恒重定向。一旦申请发往某个 URL,状态码返回 301,那么浏览器就会主动跳转到 header 中 Location 对应的 url。下次申请,再次向 location 对应的 url 发送申请。
- 之后每次申请都会跳转到 location 对应的 url。没有例外。
- 浏览器能够缓存从这个 url 获取的响应。
302:长期重定向。申请的资源长期从不同的 url 获取。一旦申请发往某个 URL,状态码返回 302,那么浏览器就会主动跳转到 header 中 Location 对应的 url。然而下次再次申请的时候向原来的 url 发申请。
- 每次申请不能确定是否向 Location 的 url 发申请,因而须要先想原来的 url 发送申请确定。
- 浏览器不可缓存从重定向的 url 获取到的响应。