<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>幼学笔记 &#187; get</title>
	<atom:link href="http://www.oncoding.cn/tag/get/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.oncoding.cn</link>
	<description>追寻简单生活</description>
	<lastBuildDate>Sun, 29 May 2011 14:03:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>寻根究底：Ajax请求的GET与POST方式比较</title>
		<link>http://www.oncoding.cn/2009/ajax-get-post/</link>
		<comments>http://www.oncoding.cn/2009/ajax-get-post/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 13:38:05 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[post]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=480</guid>
		<description><![CDATA[YSlow里有一条规则叫Use GET for AJAX requests，即“使用GET方式请求AJAX”，YSlow中的解释如下： When using the XMLHttpRequest object, the browser implements POST in two steps: (1) send the headers, and (2) send the data. It is better to use GET instead of POST since GET sends the headers and the data together (unless there are many cookies). IE&#8217;s maximum URL length is 2 [...]]]></description>
			<content:encoded><![CDATA[<p>YSlow里有一条规则叫<a target="_blank" href="http://developer.yahoo.com/performance/rules.html#ajax_get">Use GET for AJAX requests</a>，即“<strong>使用GET方式请求AJAX</strong>”，YSlow中的解释如下：</p>
<blockquote><p>When using the XMLHttpRequest object, the browser implements POST in two steps: (1) send the headers, and (2) send the data. It is better to use GET instead of POST since GET sends the headers and the data together (unless there are many cookies). IE&#8217;s maximum URL length is 2 KB, so if you are sending more than this amount of data you may not be able to use GET.</p></blockquote>
<p>翻译：</p>
<blockquote><p>当使用XMLHttpRequest对象时，浏览器通过两个步骤实现POST：(1)发送请求头；(2)发送数据。而GET的请求头和数据是一起发送的(除非包含很多cookie)，所以使用GET方式更好些。IE支持的最大URL长度是2KB，所以你的数据很长的话就不能用GET了。</p></blockquote>
<p>这段话蜻蜓点水，只说了GET和POST的这两个差别，而实际使用中会是这么简单吗？</p>
<h3>寻根：GET与POST的差别</h3>
<p><span id="more-480"></span></p>
<p><a href="http://www.rfc2616.com/" target="_blank">RFC2616</a>中详细定义和解释了<a href="http://www.rfc2616.com/#9.3" target="_blank">GET</a>和<a href="http://www.rfc2616.com/#9.5" target="_blank">POST</a>，简单来说，<strong>GET和POST的根本区别如下：</strong></p>
<p>GET通过URL传递参数(以本文的动态地址 http://www.oncoding.cn/?p=480 为例)，同时发送请求头，从服务器取得数据：</p>
<blockquote>
<p>GET /?p=480 HTTP/1.1</p>
<p>Host: www.oncoding.cn</p>
<p>Mozilla/5.0</p>
<p>&#8230;.</p>
</blockquote>
<p>POST也需要URL和请求头，同时需要额外发送数据到服务器，然后取得服务器响应，其数据格式如下：</p>
<blockquote>
<p>POST /wp-login.php HTTP/1.1</p>
<p>Host: www.oncoding.cn</p>
<p>User-Agent: Mozilla/5.0</p>
<p>&#8230;.</p>
<p>userid=admin&#038;password=asdfg</p>
</blockquote>
<p><strong>GET和POST为什么有速度的差异？</strong></p>
<p>如YSlow所说，POST比GET多出了一个发送数据的步骤，我们可以通过MIDP实现GET和POST的程序代码来理解这一个过程：</p>
<pre class="brush: java; title: ; notranslate">
// MIDP实现GET的过程(变量定义省略)：
conn = (HttpConnection) Connector.open( url ); //建立连接
conn.setRequestProperty( &quot;User-Agent&quot;, agent ); //设置请求头

int rc = conn.getResponseCode(); //取得响应
// ....
// MIDP实现POST的过程(encodedData为post数据)：
conn = (HttpConnection) Connector.open( url ); //建立连接
conn.setRequestMethod( HttpConnection.POST ); //设置请求头
conn.setRequestProperty( &quot;User-Agent&quot;, agent );
conn.setRequestProperty( &quot;Content-Type&quot;, type );
conn.setRequestProperty( &quot;Content-Length&quot;,
				encodedData.length() );

OutputStream os = conn.openOutputStream(); //发送数据
os.write( encodedData.getBytes() );

int rc = conn.getResponseCode(); //取得响应
</pre>
<p>以上程序摘自<a href="http://developers.sun.com/mobility/midp/ttips/HTTPPost/" target="_blank">HTTP POST Basics</a>。</p>
<p>分析可见，速度的差别确实出在这一个发送数据的环节上，这一环节究竟耗时多少，我们一会儿来测一下。</p>
<p><strong>何时用GET，何时用POST</strong></p>
<p>这个问题不该在我们话题的讨论之列。关于使用场合的差别，无非有两个因素：</p>
<blockquote>
<p>1. POST比GET更安全。因为GET数据可以缓存，url可以被人轻松的得到，而Ajax中不存在这个问题；</p>
<p>2. IE支持url最长为2KB，所以参数过长不能用GET，这条是Ajax需要考虑的地方。</p>
</blockquote>
<h3>究底：Ajax的GET与POST在速度上有多少差别</h3>
<p>刚刚有老外写的一篇<a target="_blank" href="http://dotnetperls.com/get-post-performance">GET and POST Requests in AJAX</a>，比较GET和POST在Ajax中的速度问题，写的洋洋洒洒，但通篇没有一点数据和理论，各浏览器的测试结果居然只有”Very slow”和”Fast”。。。</p>
<p>我们干脆自己写程序来测试一下，通过发送Ajax请求前和接收到Ajax数据后的时间差，来测试其速度的差异。使用了纯Javascript和jquery两种方式作比较。</p>
<p><a href="http://www.oncoding.cn/demos/getpost/" target="_blank">测试DEMO在这里</a>  |  <a href="http://www.oncoding.cn/demos/getpost/demo.zip" target="_blank">下载测试程序包(请根据网速，酌情修改请求时间间隔，否则会引起混乱)</a></p>
<p>手头的几个浏览器测试了一下，PHP程序放在美国Dreamhost服务器上，通过山东电信网络测试结果如下：</p>
<p><strong>Firefox 3.5</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff3_5.jpg" alt="" title="" width="481" height="133" class="aligncenter size-full wp-image-488" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff3_5_j.jpg" alt="" title="" width="494" height="135" class="aligncenter size-full wp-image-493" /></p>
<p><strong>Chrome 4.0.266 Beta</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/chrome4.jpg" alt="" title="" width="357" height="122" class="aligncenter size-full wp-image-491" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/chrome4_j.jpg" alt="" title="" width="358" height="120" class="aligncenter size-full wp-image-492" /></p>
<p><strong>IE8</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie8.jpg" alt="" title="" width="476" height="121" class="aligncenter size-full wp-image-490" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie8_j.jpg" alt="" title="" width="488" height="121" class="aligncenter size-full wp-image-504" /></p>
<p><strong>虚拟机中的IE6：</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie61.jpg" alt="" title="" width="474" height="121" class="aligncenter size-full wp-image-506" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie6_j1.jpg" alt="" title="" width="489" height="121" class="aligncenter size-full wp-image-507" /></p>
<p><strong>虚拟机中的Firefox 2.0：</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff2.jpg" alt="" title="" width="479" height="134" class="aligncenter size-full wp-image-508" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff2_j.jpg" alt="" title="" width="490" height="134" class="aligncenter size-full wp-image-505" /></p>
<p>通过对这几个流行的浏览器的测试，发现<strong>POST确实比GET要慢，而慢的这个时间基本等于服务器的响应时间(Ping值)</strong>。浏览器之间的差距不大，Firefox3.5和Chrome4速度比IE要快一点。通过jQuery进行Ajax调用比纯JavaScript稍快(是jQuery做了优化还是我JS程序写的不好？)。</p>
<p>其他浏览器有时间再测试一下，也欢迎有条件的朋友帮忙测试。</p>
<h3>后记</h3>
<p>为什么要寻根究底研究这个东西呢？</p>
<p>源于同事开发中遇到的一个问题——使用beforeunload事件，在用户关闭浏览器时通过Ajax向服务器发送数据，使用的POST方式。</p>
<p>在分析数据时，发现有一种情况，得到了请求头信息，却没有得到Ajax数据。虽然这部分数据很少，但引起了我的兴趣，同时把心里一直不明白的这个问题搞清楚了。<del datetime="2009-12-31T00:52:45+00:00">通过这通分析知，这种情况的原因可能是浏览器在得到服务器响应之前，就关闭了连接，而Ajax的异步调用方式，致使beforeunload不会等待Ajax返回，导致POST数据未能发送。解决方法，可以将数据发送改为同步方式。</del>(这个设想不成立，因为发送请求不是异步的，所以原因可能在别的地方。)</p>
<p style="text-align: right;"><a href="http://www.oncoding.cn/2009/ajax-get-post/">幼学笔记</a>原创内容，根据<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/">CC协议</a>发布，欢迎具名转载。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2009/ajax-get-post/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

