fetch 如何處理 302?
作者:時傾
來源:SegmentFault 思否社區(qū)
問題描述
fetch 發(fā)送一個請求,請求登錄過期返回 302,瀏覽器自動重定向到 Response Headers 的 Location 登錄頁面。Location 對應的服務器不接受跨域請求,因此頁面報錯。
嘗試在 fetch 的回調(diào)函數(shù)處理,一旦 fetch 的 response status 是 302 就跳轉(zhuǎn)到 Location 頁面, 但是不論在fetch的回調(diào)函數(shù)中做任何事情,都執(zhí)行不到。

什么是 HTTP 狀態(tài)碼 302 ?
HTTP 302 重定向狀態(tài)碼表明請求的資源被暫時的移動到了由Location頭部指定的 URL 上。瀏覽器會重定向到這個URL, 但是搜索引擎不會對該資源的鏈接進行更新。
使用場景:
在 OAuth 流程中,302 經(jīng)常使用;
有時候請求的資源無法從其標準地址訪問,但是卻可以從另外的地方訪問。在這種情況下可以使用臨時重定向。
搜索引擎不會記錄該新的、臨時的鏈接。在創(chuàng)建、更新或者刪除資源的時候,臨時重定向也可以用于顯示臨時性的進度頁面。
fetch 為什么不能攔截302?
fetch 發(fā)送請求;
服務器返回 response 并且?guī)в袪顟B(tài)碼(比如200) ;
瀏覽器接收到響應,結(jié)果遞交給fetch;
從 fetch 的回調(diào)函數(shù)獲取相應數(shù)據(jù);

fetch 發(fā)送請求;
服務器返回 response (帶有l(wèi)ocation) 并且?guī)в?302 狀態(tài)碼;
瀏覽器接收到響應,自動從302響應的頭信息的重定向地址中取到 location 進行跳轉(zhuǎn);
如何解決?
1. 配置 fetch 的 redirect
follow:默認, 自動重定向;
error:如果產(chǎn)生重定向?qū)⒆詣咏K止并且拋出一個錯誤;
manual:手動處理重定向;
error
fetch 只有服務器錯誤才調(diào)用 catch,其他都會調(diào)用 then 函數(shù),那么 302 為什么會調(diào)用catch? 不是 302 導致 catch 被調(diào)用而是重定向后的請求的 response 導致 catch 被調(diào)用。

manual

2. 后端改寫狀態(tài)碼,前端手動處理
301 和 302 狀態(tài)碼區(qū)別
之后每次請求都會跳轉(zhuǎn)到 location 對應的url。沒有例外。
瀏覽器可以緩存從這個 url 獲取的響應。
每次請求不能確定是否向 Location 的 url 發(fā)請求,因此需要先想原來的 url 發(fā)送請求確定。
瀏覽器不可緩存從重定向的 url 獲取到的響應。
重定向可以用來set cookie
用戶訪問 a 域名
后端返回302,location是 b 域名,同時set-cookie: cookieA
瀏覽器在 a 域名下種上cookie: cookieA,然后向 b 域名發(fā)起請求
后端返回 302,location 是a 域名,同時 set-cookie: cookieB
瀏覽器在 b 域名下種上cookie: cookieB,然后向 a 域名發(fā)起請求
其實跨域 set cookie 還可以用瀏覽器的 beacon API 實現(xiàn),當然也是有一些限制的 重定向可以有多次,比如連續(xù)的302, 就是 location 對應的 URL 又返回了 302 和新的location,如此重復直到不再跳轉(zhuǎn)位置。為了防止出現(xiàn)無限重定向的情況,重定向的次數(shù)是有上限的。Chrome 瀏覽器的重定向次數(shù)是20,超過20次重定向就會報ERR_TOO_MANY_REDIRECT錯誤。

