fetch捕获重定向302/301

  1. 读完本文大约须要5分钟
  2. 本文前置知识:HTTP状态码、fetch
  3. 阅读难度:初级
  4. 本文关键代码及输出结果都写了出来,能够不用编译器编译,直接浏览文章



事情发生在昨天,在调用接口的时候,接口写错了:前端

/xxx/interventionlist 写成了 /xxx/Interventionlist后端

果不其然红一片,点开network后,找到调用的接口 ⬇️浏览器

这里的302是对404处理后的结果,将全部出现404的结果跳转到一个指定的404页面。 不过这种跳转应该发生在访问页面时,而不是在调用接口传参交互时。安全

所以我决定对这种出现302的错误进行一个封装,在亲自踩过坑后,这篇文章诞生了!服务器


重定向时没法直接捕获状态码

最开始我尝试直接作个 checkStatus() 来处理这种问题,当response.status === 302console.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(...)
复制代码

结果啥都没输出,注一、注2的console.log都没有输出内容fetch

咱们梳理一下请求的流程ui

fetch 发送请求 -->url

服务器返回 response 而且带有状态码(好比200) -->spa

浏览器接收到响应,结果递交给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改写成自定义状态码,而后前端捕获到这个状态码后,进行手动处理。

这种方法则须要先后端的同窗都作处理。

相关文章
相关标签/搜索