fetch無法獲取302響應的header信息:
- 瀏覽器對於302狀態重定向,是直接進行重定向。
- 且js的fetch請求無法獲取(catch也好、then也罷)到302響應的header信息,自然也無法得到header里的location字段,無法根據location值,進行重定向(window.location.replace(url))
- fetch不能攔截302,瀏覽器會自動從302響應的頭信息的重定向地址中取到數據。針對認證的情況,后端可以返回401狀態碼,讓前端去檢查返回的狀態碼並據此執行相應操作。
-
對於重定向,當瀏覽器檢查到headers中存在Location,會直接進行跳轉,不會告知任何請求發送者(fetch),這時候發送者會以為請求還在處理中。所以此時的fetch的then和catch都捕獲不到信息。
解決辦法,思路:
- 修改HttpResponseRedirect的響應碼為非302值,因為django的302響應碼是由HttpResponseRedirect決定的。重新HttpResponseRedirect或者其子類
- 使用中間件,在最后攔截所有響應,把響應里的302修改為其他值
fetch請求舉例:
// Example POST method implementation: postData('http://example.com/answer', {answer: 42}) .then(data => console.log(data)) // JSON from `response.json()` call .catch(error => console.error(error)) function postData(url, data) { // Default options are marked with * return fetch(url, { body: JSON.stringify(data), // must match 'Content-Type' header cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached credentials: 'same-origin', // include, same-origin, *omit headers: { 'user-agent': 'Mozilla/4.0 MDN Example', 'content-type': 'application/json' }, method: 'POST', // *GET, POST, PUT, DELETE, etc. mode: 'cors', // no-cors, cors, *same-origin redirect: 'follow', // manual, *follow, error referrer: 'no-referrer', // *client, no-referrer }) .then(response => response.json()) // parses response to JSON }
var url = 'https://example.com/profile'; var data = {username: 'example'}; fetch(url, { method: 'POST', // or 'PUT' body: JSON.stringify(data), // data can be `string` or {object}! headers: new Headers({ 'Content-Type': 'application/json' }) }).then(res => res.json()) .catch(error => console.error('Error:', error)) .then(response => console.log('Success:', response));
重定向時的過程:
fetch 發送請求 --> 服務器返回 response(帶有location) 並且帶有狀態碼302 --> 瀏覽器接收到響應,通過location進行跳轉 --> 服務器返回 response 並且帶有狀態碼(比如200) -->
瀏覽器接收到響應,結果遞交給fetch -->
我們從fetch的回調函數獲取相應數據
參考:
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
https://www.jianshu.com/p/2043bd31cb83
https://juejin.im/post/5bf7759df265da613f2f1f6f
