HTTP301永久重定向引发的灾难性后果

对于交易系统利用重定向做分流时,需要考虑清楚业务场景和实际的功能实现,再做定夺。

HTTP重定向问题

301永久重定向,从字面上理解,它很可能就是业务需要的解决方案,因为永久和重定向这两点通常都是符合需求的。浏览器对于301的理解,可能会更深入一些,通常在浏览器没有禁用缓存时(默认),当对一个地址发起http请求(如:https://e.xieyonghui.com/a),如果服务端给浏览器返回301状态码(重定向到https://e.xieyonghui.com/b),浏览器会默认缓存这个请求地址(https://e.xieyonghui.com/a),当再次访问https://e.xieyonghui.com/a时,浏览器默认直接读缓存,此时从浏览器调试控制台,可以看到Status Code: 301 Moved Permanently (from disk cache),这一行为不受用户意愿控制。

这一行为有可能导致用户看到的,始终是第一次请求的数据(这个与功能的实现方式有关),在一些业务场景中,这一点是可以接受的,甚至是所期望的;但如果这一行为应用到一些交易场景中,可能出现一些无法预知的行为。如,用户反复编辑购物清单(或购物车),如果在功能实现时不考虑这一点,就可能我非出现展示数据与实际操作不符的现象。

解决方案

1、在链接参数中追加uuid防止读取缓存。

或者

2、在重定向命令中为Reponse Headers加入Cache-Control no-store参数。以Nginx配置为例:

location / {
            add_header Cache-Control no-store;           
            rewrite ^/(.*)$ https://xieyonghui.com/$1 permanent;

}

如果参数配置未生效,两种可能:1:Reponse Headers参数中有其他参数冲突。2:先禁用浏览器缓存后,读取一次,再进行测试。

http常用30x系列:

Status Code: 301 Moved Permanently
Status Code: 302 Moved Temporarily
Status Code: 303 See Other 
Status Code: 307 Temporary Redirect

都存在[from disk cache]的可能,关于HTTP 30x参数说明参见developer.mozilla.org

Nginx 30x系列参数设置

rewrite ^/(.*)$ https://e.xieyonghui.com/$1 permanent; #301
rewrite ^/(.*)$ https://e.xieyonghui.com/$1 redirect; #302
return 307 https://e.xieyonghui.com/$1; #30x

Nginx1.1.16之前版本没有正确支持返回307响应。