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改寫成自定義狀態碼,而後前端捕獲到這個狀態碼後,進行手動處理。

這種方法則須要先後端的同窗都作處理。

相關文章
相關標籤/搜索