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