Chrome在302重定向的时候对原请求产生2次请求的问题说明
这个问题应该确确实实是一个Chrome的BUG,我在自己的编程环境中发现,并在多个服务器,多个编程语言的运行环境,以及多个浏览器下都测试过,都看到有2次请求出现。为了证明不是自己环境的问题,我也特意去找了一些其他站点,用它里面的一些会产生重定向的请求来测试。比如这个请求地址http://wenda.golaravel.com/account/openid/qq_login/,这是golaravel问答模块进行qq登录的链接地址,它会重定向到qq授权登录的页面。
使用fiddler监控wenda.golaravel.com这个站点,然后在Chrome里面访问以上地址,回到fiddler查看监控结果:
从这个结果可以明确地看到,Chrome对这个地址发出了2次http请求,并且这两次http请求都从服务器拿到了Response。从fiddler的Statistics栏里面,可以对比看出这两个请求过程的一些信息:
第一个是:
第二个是:
从这个对比结果可以看到,这两个请求并不是一种串行的关系,而是并行的关系。但是这个问题的特性还不止这么简单,目前我发现的一些现象如下:
1)不是每次都会出现这个情况,我只能说大部分测试操作都出现这种情况,但是少部分情况是正常的:访问302的地址,对原地址只发起了一次请求,第二次是对302 Location指定的地址的请求,这是正常的;
2)这两个请求并不是每次都能成功从服务器拿到响应,有的时候其中的一个会报500的错误,或者是显示failed,此时如果观察fiddler的log记录,会看到有下面的一些关键信息:
Session #143 raised exception System.Net.Sockets.SocketException
//or
This request was retried after a Receive operation failed.
3)大部分情况下,都是这两个请求先发起,然后再对302 Location重定向请求;但是极少的情况会遇到302重定向请求夹在这两个请求中间。
目前我并没有找到这个问题产生的原因,网上相关的资料太少了,所以我只能从多个方面来验证是否是Chrome本身的问题,最后得出的结论也跟我的猜想一致,这就是Chrome较新版本的一个BUG,我在当前时间点的最新版本的Chrome浏览器里面看到这个现象的:
下面我会详细地证明它是否为Chrome的一个BUG。
1. 问题的发现
我使用laravel框架写了一个很简单的程序,就几个页面,做微信登录的demo用的,所以页面里的微信登录按钮,实际上就是一个需要重定向到微信授权页面的地址。我在浏览器里面访问这个地址的时候,在本地windows下的apache服务器的access.log里面,发现这一个访问操作产生了三次http请求:
从这个日志里很明显地看到有2次对/login/weixin的请求,这个就是重定向请求的原请求记录。发现这个问题之后,我并不认为是服务器或者浏览器的问题,而是首先怀疑是否是自己代码里面有重定向loop的情况。所以第一步就去仔细地检查自己的代码:
/**
* 微信登录
* @param Request $request
* @return mixed
*/
public function weixin(Request $request)
{
$q_str = $request->getQueryString(); return Socialite::with('weixin')
//设置授权的回调地址,通过命名路由的形式
->setRedirectUrl(route('notify_weixin') . ($q_str ? '?' . $q_str : ''))
->redirect();
}
最后的redirect方法是:
/**
* 重定向并将state参数写到cookie里面去,而不是采用session
* @return string
*/
public function redirect()
{
$state = $this->getState(); $response = new RedirectResponse($this->getAuthUrl($state), 302, [
'Set-Cookie' => implode('', [
$this->state_cookie_name,
'=',
$this->getEncryptState($state),
"; path=/; domain=",
$this->getDomain(),
"; expires=" . gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT", time() + $this->state_cookie_time),
"; Max-Age=" . $this->state_cookie_time,
"; httponly"
])
]); return $response;
}
这个代码里的RedirectResponse是laravel框架提供的类。从这个代码,我并没有看出什么问题,因为没有多次创建Response的处理。所以开始怀疑是否是新版的laravel框架的问题,因为我用的是最新的laravel框架。所以我又用公司的php环境测试了一下,公司的php环境用的yii这个php框架,结果发现,公司的环境在本地依然存在这个问题。
为了排除是框架的问题,我又自己写了两个最简单的php页面:
我把demo1部署到demo1.com,demo2部署到demo2.com,然后访问demo1.com来测试。最后也还是遇到了这个问题。在这一次测试里面,我还发现了有两个关键点:
1)如果把302改成301重定向,那么chrome就不会产生两次请求。但是实际上301用在这里是不对的,因为它的含义是原地址的资源已经永久转移到别的位置了。
2)这个问题导致的两次对原地址的请求,大部分情况下,服务器都能收到并进行处理。(demo1里面的打印信息,在这个问题出现的时候,每次都打印两个时间信息,说明服务器响应了2次)。这意味着用户的一次访问操作,浏览器发出了2个请求,服务器对同一个用户操作进行了2次处理。这并不是个没有影响的事,比如当这个请求对某个资源的状态做了一些持续性的改变时,如数据累计,那就意味着用户一次操作,就会累计2次,这样这些数据结果可能就有问题了。这也是我把这个问题详细记录说明的主要原因,我觉得开发中应该注意到这个问题的存在,以便在排除一些疑难的数据问题的时候,可以思考到这个层面上来。
到此为止,基本上已经排除是php框架的问题了。接下来考虑的问题产生对象主要是编程语言,服务器以及浏览器。
2. 排查是否为编程语言的问题
为了验证是否为php语言本身的问题,我又用express框架写了以下简单代码,并运行在node的环境里面来测试:
app.get('/', function (req, res) {
res.redirect('/redirect');
}); app.get('/redirect', function (req, res) {
res.send('success');
});
最后测试发现这个问题,在Nodejs里面同样存在。所以也可以排除是php语言的问题了。
3. 排查是否为服务器的问题
因为这个问题本身是在本地windows服务器里面发现的,所以我怀疑是否为本机apache的问题,所以我又把相关的代码部署到远程的nginx服务器上,最后同样测试到这个问题的存在。
加上上一步在nodejs里面测试的时候,实际上是用本机的node服务器运行的,综合这两个服务器测试结果,也能证明并不是apache服务器的问题。
4. 排查是否为浏览器的问题
我的机子上有360浏览器,firefox,IE11,Edge浏览器和最新的Chrome浏览器的。最后测试发现只有Chrome浏览器里面有这个问题,其它浏览器测试,在fiddler里面都只能看到对原地址仅发起了一次http请求,在每个浏览器我都重复做了大概十多次访问操作才得出这个结论。为了进一步验证Chrome的版本问题,我又特意删了当前版本,下载了一个Chrome46的浏览器测试,结果没有发现这个问题。到此为止,也就基本上可以认为是Chrome浏览器的问题。
5. 进一步排查是否为本机运行环境的问题
为了进一步排查是自己开发环境的问题,我专门到网上找了一些其他站点的302请求地址做测试。除了本文开头提供的地址,下面这个地址也可以测试:
最后,根据以上的排查内容,可以认定这个问题是Chrome的一个BUG,我已经report给他们了,回不回复不重要,最重要的是下一个版本这个问题是否能够解决。所以接下来这个问题,我的处理方式是:跟进chrome的版本更新情况,并在新版本中进行测试。希望它能在后续的版本中得到解决。
其实在以上排查过程中,还有一些情况值的考虑,比如操作系统环境,网络环境的影响,毕竟http请求本身处于这两个大的因素之下,所以也不能完全排除它们的原因。所以,要是感兴趣的朋友,觉得这个问题值得研究的话,非常希望你能把自己的测试结果反馈过来,如果这个问题在你的机器上也存在,那么就能增加本文的客观性和正确性,就能帮助更多的人;如果很多人都没有测试出这个问题,就说明本文的结论有误,这篇文章应该作废才行。
Chrome在302重定向的时候对原请求产生2次请求的问题说明的更多相关文章
- HTTP GET请求302重定向问题
1.问题描述 ① 在华为云服务器中搭建了java环境,并在tomcat中部署了一个空的web项目 ② 在此web项目中上传了一个名为:plugin_DTDREAM_LIVING_DEHUMIDIFIE ...
- Scrapy爬虫返回302重定向问题解决方法
scrapy爬虫遇到爬取页面时302重定向导致response页面与实际需要爬取的页面信息不一致,导致无法正常获取信息,查看日志存在 scrapy.downloadermiddlewares.redi ...
- Http状态码之:301、302重定向
概念 301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一.如果可能,拥有链接编辑功能的客户端应当自动把请求的地 ...
- RestTemplate 支持服务器内302重定向
Stack Overflow 里找到的代码,可以正常返回服务器302重定向后的响应 final RestTemplate restTemplate = new RestTemplate(); fina ...
- httpclient自动执行http的302重定向
今天debug过程中发现,httpclient会自动执行302的重定向,但是这个的前提是第一个请求是get发出的.我测试发现用post的后的302是系统不会自动redirect的..不知道到底正确不, ...
- HTTP 状态码之:301、302 重定向
转自:http://www.cnblogs.com/5207/p/5908354.html 概念 301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用 ...
- 302重定向之后,session中存储的值没了
302重定向之后,session中存储的值没了
- 请求转发(forward)和请求重定向(redirect)的区别(转)
作者:@haimishasha本文为作者原创,转载请注明出处:https://www.cnblogs.com/haimishasha/p/5952129.html 用户向服务器发送了一次HTTP请求, ...
- HttpClient如何解决302重定向问题
最近的接口测试,发现接口地址报302错误,通过上网搜索,发现问题所在,解决办法是需要请求重定向后的URI. package com.btv; import org.apache.http.Header ...
随机推荐
- 前端开发中SEO的十二条总结
一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...
- .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]
方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...
- WPF 微信 MVVM
公司的同事离职了,接下来的日子可能会忙碌,能完善DEMO的时间也会少了,因此,把做的简易DEMO整体先记录一下,等后续不断的完善. 参考两位大神的日志:WEB版微信协议部分功能分析.[完全开源]微信客 ...
- 写出易调试的SQL
h4 { background: #698B22 !important; color: #FFFFFF; font-family: "微软雅黑", "宋体", ...
- js学习之函数的参数传递
我们都知道在 ECMAScript 中,数据类型分为原始类型(又称值类型/基本类型)和引用类型(又称对象类型):这里我将按照这两种类型分别对函数进行传参,看一下到底发生了什么. 参数的理解 首先,我们 ...
- iOS微信里打开app,Universal Links
这两天在弄分享,从第三方应用或者浏览器打开自己app的东西 传统的方式是通过URL Scheme的方式,但是iOS9以后又出了新的更完美的方式Universal Links. 传统的URL Schem ...
- ResponsibleChain(责任链模式)
/** * 责任链模式 * @author TMAC-J * 老板讲任务交给CTO,CTO自然不会亲自去做,又把人物分配给项目经理,项目经理再把任务分配给组长,组长再分配给个人 * 如果中途哪个环节出 ...
- 推荐10款超级有趣的HTML5小游戏
HTML5的发展速度比任何人的都想像都要更快.更加强大有效的和专业的解决方案已经被开发......甚至在游戏世界中!这里跟大家分享有10款超级趣味的HTML5游戏,希望大家能够喜欢! Kern Typ ...
- 微信小程序开发日记——高仿知乎日报(上)
本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...
- 编译器开发系列--Ocelot语言5.表达式的有效性检查
本篇将对"1=3""&5"这样无法求值的不正确的表达式进行检查. 将检查如下这些问题.●为无法赋值的表达式赋值(例:1 = 2 + 2)●使用非法的函数 ...