AJAX調用慎用POST方式,有嚴重的問題或者BUG

來源:互聯網
上載者:User

這個問題只存在用戶端是IE或IE核心的情況,但是你無法控制用戶端使用什麼瀏覽器,所以仍然會給你的應用造成很大的效能問題。

我們先說現象:

服務端:我們只用一個靜態HTML頁面ok.html,內容只返OK.

然後我們寫一個ajax調用的html在用戶端訪問:

<script>function send_request(method,url,param) {    http_request = false;    if (window.XMLHttpRequest) {        http_request = new XMLHttpRequest();    } else if (window.ActiveXObject) {        try {            http_request = new ActiveXObject("Msxml2.XMLHTTP");        } catch (e) {            try {                http_request = new ActiveXObject("Microsoft.XMLHTTP");            } catch (e) {            }        }    }    if (!http_request) {        return;    }    http_request.open(method, url,true);    http_request.send(param);}function get(){    var url = "http://myhost/ok.html?name=axman&test=123";    for(var i=0;i<1000;i++){        send_request("GET",url,null);    }}function post(){    var url = "http://myhost/ok.html";    for(var i=0;i<1000;i++){        send_request("POST",url,'name=axman&test=123');    }}</script><input type="button" name="b1" value="get" onclick="get()"><input type="button" name="b2" value="post" onclick="post()">

這個頁面上兩種方式訪問和傳遞的參數完全一致,當我按下get按鈕後,服務端收到了1000個訪問記錄。

[admin@vm-platform access_log]$ cat apache_access.log.4 |wc -l
1000
然後我統計訪問時間大於1ms的記錄:

[admin@vm-platform access_log]$ cat apache_access.log.4 |awk '{if($12 > 1000) print $0}'

結果是空。

現在我們再按下POST按鈕:

[admin@vm-platform access_log]$ cat apache_access.log.4 |wc -l
2000

當服務端顯示2000時,說明訪問完成。

[admin@vm-platform access_log]$ cat apache_access.log.4 |awk '{if($12 > 1000) print $0}'的結果:

10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 696078 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 696045 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 695776 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 695332 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 696500 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 696484 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 696215 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 696235 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 696182 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:55 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 694964 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:58 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 1274 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -
10.16.14.82 - - - [24/Nov/2011:16:08:59 +0800] "POST /myhost/ok.html HTTP/1.1" 200 20 1019 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" - - "a=-; b=-; c=-" -

請注意apache %D記錄的時間是從第一個頭域(讀到第一個換行斷行符號開始)記時到響應輸出(協議層,只要寫到BUFF中,不一定已經發送到用戶端)。這個時間單位是

微秒,請看一下其中有10條記錄近700ms,是get方式的千倍。

因為這個現象給我們的兩個應用帶來效能問題,我開始分析這個原因,後來從網上搜尋到文章說IE核心的瀏覽器在AJAX調用時,對POST方式採用兩步發送,第一次發送

頭域,第二次發送BODY。中間有很大的延遲,有時還會造成BODY包丟失,我們從網路抓包的情況看,確實存在只發送了HEADER,後面只有服務端逾時返回的錯誤資料包,再也沒有BODY的資料。這樣的機率大約有1%.

 

這個問題在apache作為proxy時,proxy就不能在有效時間內將用戶端請求發送給backend,造成大量的內部錯誤輸出。如果是SS還會引起資料時序混亂。在發送\r\n\r\n後頭域還有尾巴沒有發送完成,這些現象都是從網路抓包監控到的。

如果換成fireFox,同樣的AJAX代碼執行POST就沒有問題,關鍵是你根本無法控制使用者不使用IE。

網上給出的解決方案試了一下根本不起作用(也許IE6可以起作用,我用的IE8就沒有細測IE6),關鍵是只要部分瀏覽器發生這個情況,就會給應用帶來很大的效能問題。

所以盡量少使用AJAX的POST方式提交資料,但是有時服務端為了安全的原因只允許POST提交,可以動態構造FORM表單,而盡量少使用AJAX來調用POST。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.