一、起因
最近系统需要接入微信登陆,就研究了下各大平台的微信登陆功能(app/web页面),也由此突然对重定向的原理产生了兴趣,以前只知道重定向是浏览器自动完成(根据响应的状态码是不是3开头判定),开发人员并不需要知道这一过程的具体实现,用户也不会感知到重定向的发生。单浏览器如何获取到重定向的目标链接倒是一直没有思考过。
二、假设结论
因为浏览器是基于http协议工作的,所以初步判断是通过响应头/响应体某个字段获取的目标url,带着假设进行试验。
三、测试
测试使用的链接是京东的微信登陆,如下:
window.location.href是获取当前页面url链接中?后面部分的。所以我们要测试的链接地址实际便是:http://qq.jd.com/new/wx/login.action?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F
得到的重定向链接是:
https://open.weixin.qq.com/connect/qrconnect?appid=wx827225356b689e24&state=5176093BC83D54F3DA6E9C6D86E0895BF22E09AA1A80DE98A18E50EA0FA4DC3CE875D78FC6FF2E21B84C4B27AA29CCE5&redirect_uri=https%3A%2F%2Fqq.jd.com%2Fnew%2Fwx%2Fcallback.action%3Fview%3Dnull%26uuid%3D45a70094881945c58fde87a9878e6c12&response_type=code&scope=snsapi_login#wechat_redirect
3.1 测试结果如下
3.1.1响应头:
3.1.2 响应体:
果然如原先设想的那样,响应头里有个属性值是链接,但这个链接怎么和请求的url是‘一样’的?我推翻了自己认为浏览器是从响应头/响应体中获取重定向url的假设。于是我去问了几个同事,他们也没有思考过这些。。。没办法,只能去咨询领导,得到了就是通过location获取重定向url的结论,但我不信,我觉着location的url和当前url明明是‘一样’的怎么可能实现重定向,一定是领导错了!于是乎,我又向度娘咨询location属性的作用,然后度娘站在了我领导的旁边。。。
我有点绝望了,抓耳挠腮是哪里出了问题,为什么响应头的location和最终重定向的url并不一样?这时候我想会不会是postman的问题,于是就尝试在shell中用wget命令直接请求。结果如下:
突然发现了盲点----怎么会出现两次302重定向?而且第二次重定向的location是正确的。这时候我才发现第一次重定向的location和源url的区别----源url是http,而location的是https的!赶紧用在源url前加上https用postman再试了一次,结果对啦,截图如下:
原来京东强制使用https协议,但用户使用时候基本不会在链接前输入https,所以京东在服务器将http重定向到https(如nginx),这也就造成了第一次重定向的location看起来和源url‘一样’。
四、结论
是否需要重定向是根据状态码是否为3开头判断,重定向的url是从响应头的location字段获取。