本文转载自https://blog.csdn.net/handsomekang/article/details/78650513

事情是这样的。移动端的同事在调用Django接口时,明明已经有登录态,却返回未登录。于是app以为是token过期,刷新token再请求,再提示未登录,如此反复,造成了死循环。


查看日志,发现是URL后面少了斜杠,由于Django中设置了APPEND_SLASH=True, 当URL后面缺少斜杠时,会自动拼上斜杠,并重定向。


那为什么重定向之后,登录态就丢失了呢?更奇怪的是看日志发现原本是一个DELETE方法的请求,重定向后变成了GET请求。


原因是这样的。 

我们的凭证是放在HTTP的header的Authorization里面。而重定向的时候这个数据丢失了。


看了一下RFC 2616,里面写到


The new permanent URI SHOULD be given by the Location field in the 

response. Unless the request method was HEAD, the entity of the 

response SHOULD contain a short hypertext note with a hyperlink to 

the new URI(s).


If the 301 status code is received in response to a request other 

than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might 

change the conditions under which the request was issued.


Note: When automatically redirecting a POST request after 

receiving a 301 status code, some existing HTTP/1.0 user agents 

will erroneously change it into a GET request.


当返回状态码301重定向的时候,response的header里Location字段设置为重定向后的URL。如果请求方法不是GET或HEAD,客户端不应该自动跳转到重定向后的URL,除非用户明确要这样做。


其实,当客户端收到301状态码时,要不要跳转过去,要不要带上Authorization头,要不要将非GET方法转成GET方法,是客户端决定的。 

比如,浏览器收到一个GET请求的301重定向,会自动跳转过去。而在客户端Paw发请求,得勾选Follow Redirects才行。


另外,Paw还可以勾选Redirect Authorization和Redirect Original Method.




结论:

要小心重定向

非GET方法还是不要自动APPEND_SLASH的好

重定向行为依赖客户端