• 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代码:

    01 <body>
    02 <script src="jquery.1.3.2.js"></script>
    03 <form method="post" action="">
    04 <select name="option" id="option">
    05     <option value="POST" name="POST">POST</option>
    06     <option value="GET" name="GET">GET</option>
    07 </select>
    08     <input  id="button"  type="button" value="POST提交">
    09 </form>
    10 <script language="JavaScript">
    11 <!--
    12 $('#button').click(function(){
    13     var option = $('#option').val();
    14     $.ajax({
    15         type: option,
    16         url:"cc.php",
    17         data: "name=cfc4n&option="+option,
    18         success: function(msg){
    19             alert(msg);
    20         }
    21     });
    22 });
    23 //-->
    24 </script>
    25  </body>

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

    wireshark去掉 packet reassembly选项

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

    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 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请求,抓包对比结果。

    我惊奇的发现(细心的同学会注意到第三张图中,有椭圆形的框标出那些结果的浏览器是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中)。希望你看到最后的时候,忘记标题讲的是什么。

    from: http://www.cnxct.com/use-get-for-ajax-requests-why/

  • 相关阅读:
    线程的五种状态
    ajax回调打开新窗体防止浏览器拦截有效方法
    mysql 如果字段为null自动返回需要的信息sql
    String 与 StringBuffer的区别
    Windows Git中文文件名乱码
    定义函数指针
    hello world
    C++析构函数调用异常问题研究
    企业开发的时候,有可能碰到的问题
    jmap
  • 原文地址:https://www.cnblogs.com/Langzi127/p/3047106.html
Copyright © 2020-2023  润新知