5

YSLOW法则中,为什么yahoo推荐用GET代替POST?

 3 years ago
source link: https://www.cnxct.com/use-get-for-ajax-requests-why/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

YSLOW法则中,为什么yahoo推荐用GET代替POST?

背景:
上上周五,公司前端工程师培训,提到前端优化的一些技巧,当然不能少了yahoo yslow的优化法则。其中有这么一条“Use GET for AJAX Requests”,这些法则从最开始的14条,到现在的35条,一直都时刻关注的。可这么一条的原因我却一点都不清楚。在提问的环节里,我对yahoo WEB前端优化法则推荐AJAX中,使用GET代替POST的原因有疑问,便请教前端工程师。我们的工程师说GET的话,浏览器发送一个包,POST会发两个等等。我对这个解释仍带有疑问,甚至怀疑。培训结束后,我随便搜索了一下,并没有得到理想的结果,可能很少人对Yahoo这么有权威的组织提出的优化法则产生怀疑,也很少人想知道为什么建议这么做,更多的人会唯命是从,墨守成规。之后,我又看了遍优化法则,看到一条是推荐开发者使用AJAX缓存的,这时,一个“伟大”的想法在我脑袋中一闪,莫非是GET请求可以缓存,而POST不可以?接着,我把我这个“伟大”的猜测告诉我的同事们,当初已经是下班时间,好多同事都离开公司,我也匆忙收拾东西下班了,没有仔细查找答案。

周末期间,脑袋中频繁的闪现这个问题,仍对我的想法有怀疑,Yahoo前端这么牛X的团队的想法,岂是我这样的菜鸟能这么容易的猜测推断到的?我对我当初的推测的怀疑就像“小时候就怀疑小JJ绝对不是只用来撒尿那么简单”一样坚定。但向我这么懒惰的同学,实在找不出一点时间来验证我这个想法,空闲的时间宁愿多打几盘CS。一直拖到现在,台风来了,在家宅两天,头都睡扁了,也找不出不写这篇文章的理由。

验证Yahoo推荐的理由:
验证XHR请求中yahoo推荐用GET代替POST做法的理由

POST is implemented in the browsers as a two-step process: sending the headers first, then sending data. So it’s best to use GET
POST请求分两步:发送http headers,再发送http data

HTML+JS代码:

<body>
<script src="jquery.1.3.2.js"></script>
<form method="post" action="">
<select name="option" id="option">
<option value="POST" name="POST">POST</option>
<option value="GET" name="GET">GET</option>
</select>
<input  id="button"  type="button" value="POST提交">
</form>
<script language="JavaScript">
<!--
$('#button').click(function(){
var option = $('#option').val();
$.ajax({
type: option,
url:"cc.php",
data: "name=cfc4n&option="+option,
success: function(msg){
alert(msg);
}
});
});
//-->
</script>
</body>

抓包工具:wireshark
提示:wireshark(1.2.5版)在抓http包的时候,会默认合并packet reassembly选项,记得全部去掉。如下图(edit–>Preferences)

wireshark-http-150x150.jpg

wireshark去掉 packet reassembly选项

我分别发了一个GET、一个POST的XHR(XMLHttpRequest)请求,其数据包如下:

xhr-get-post-150x150.jpg

XHR HTTP请求中GET与POST发送的数据包详情

如上图,GET请求发送的数据包为第一个红框内的结果;POST请求发送的数据包为第二个红框内结果,但多了一个第12条数据包(粉红色框内),从10.0.0.108(我的PC)发往98.126.129.106(www.cnxct.com的服务器IP,也就是表单提交的目标服务器IP),wireshark给出的信息是“Continuation or non-HTTP traffic”,这个提示就是说,本次数据包是接着上一次的HTTP请求发的,没有HTTP header,只有http data。
详情如下图
XHR HTTP POST请求的header部分数据:
xhr-http-headers-150x150.jpg

XHR HTTP POST请求的header部分数据

XHR HTTP POST 请求的DATA部分:

XHR HTTP POST 请求的DATA部分

XHR HTTP POST 请求的DATA部分

结论?:
果然,如伟大的YAhoo前端团队所说,XHR HTTP的POST请求会分为两步,先发HTTP HEADER,再发HTTP DATA部分。

然而,新的疑问又来了。为什么要分为两部?谁(例如W3C这种机构)规定的?每个浏览器都是这样的么?分两次比一次的的效率更高吗?

继续:
带这我新的疑问,又进行了如下尝试:先分浏览器,IE8、Firefox5.0、Chrome13分别发送XHR GET 、XHR POST请求,抓包对比结果。
xhr-get-post-chrome13-firefox5-ie8-150x150.jpg

我惊奇的发现(细心的同学会注意到第三张图中,有椭圆形的框标出那些结果的浏览器是Chrome13),Firefox5发送POST的数据包确是没有像yahoo前端优化法则中提到的那样,分为两次,两个包发送,而是一次完成http headers和 http data的发送。如下图:

firefox5在发送XHR POST请求时的数据包

firefox5在发送XHR POST请求时的数据包

大家可以从图中看到line-based text data:application/x-www-from-urlcoded下面就是POST的数据。
这时,又有很多疑问产生了,其他浏览器呢?IE的所有版本都会分两次发么?Firefox的其他版本呢?
当我想一个一个尝试抓包对比的同时,幸运的搜到了关于我这个疑问的PDF(Analysis_of_browser_specific_characteristics.pdf)
其中,提到firefox大部分版本在XP、WIN7、UBUNTU、MAC OS等系统上都是以1个包来实现的,其他常见浏览器都是分为两个包。

相比大家很清楚的知道,HTTP(TCP)完成一次事务,通讯次数越多,越有可能出现故障(网络延迟等因素),开销越大,浏览器(客户端)、服务端都要再进行一次TCP通讯,而且,需要一定的时间。对于我们追求更高的用户体验,需要HTTP通讯都避免到这些缺点,而各大浏览器开发商为何仍这么做呢?firefox的做法是最好的吗?

上面的PDF里,模拟了各种网络环境,比如网络延迟、网络丢包等情况,分别来对比POST请求的1次包和2次包的优缺点。得出的结论是:当网络环境好的情况下,1次包跟2次包的在时间上差别基本可以无视。而在网络环境差的情况下,(2次包)TCP的验证数据包完整性上,有非常大的优点,客户端先告诉服务端即将发送的数据包大小,MD5等标识,当服务端告诉客户端收到(ACK包)的时候,客户端再次向服务端发送POST 的DATA。假如网络环境不好,网络延迟、丢包的时候,服务端会等待(延迟时),客户端重发POST的DATA数据到服务单,来确保本次请求的完整性。

撰写这个PDF的作者在他的博客里详细的描述了写这个博客的起因,以及结果,还有一些关于与yahoo yslow前端团队的一些沟通过程,大家可以在这里阅读下(yahoo 的前端团队好像不太友好,哈)。

结论:
通过参考这个PDF,以及我自己做的抓包测试,让我了解Yahoo YSLOW前端团队的这个推荐(他们没详细的说为啥这么推荐,只是简单的提了下GET请求产生TCP一个包;POST请求,产生2个TCP包。甚至都没告诉我们Firefox的多数版本[可能是所有版本]都是发一个TCP包的。更详细、更深层原因也没说,这里还得感谢下http://loadimpact.com的作者)。

备注:
这里提供下我抓包测试时候的数据包(截图用到的数据包中包含我的一些cookie,没上传。这里的是我新抓的,各位见谅),各位可以参考下,如果我的文字、方向有错,欢迎指出。
IE8、FF5、Chrome13发起XHR请求数据包

当你读到这里时,我承认,我骗了你,文章的内容不光是标题中所写的,为何推荐使用POST代替GET,更多的是抓去TCP、HTTP通讯包来验证各个浏览器是否如YSLOW所述的那样分2次包的过程,以及2次包与1次包的优缺点(PDF中)。希望你看到最后的时候,忘记标题讲的是什么。

更新日期:2014年10月27日
在网上看到一篇文章也是介绍GET跟POST区别的,见:XMLHttpRequest (XHR) Uses Multiple Packets for HTTP POST?

莿鸟栖草堂 由 CFC4N 创作,采用 知识共享 署名-非商业性使用-相同方式共享(3.0未本地化版本)许可协议进行许可。基于http://www.cnxct.com上的作品创作。转载请注明转自:YSLOW法则中,为什么yahoo推荐用GET代替POST?

No related posts.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK