According to MDN,XMLHttpRequest
readyState
事件觸發5個事件,如下所示。XMLHttpRequest readyState HEADERS_RECEIVED等待整個文件下載
0 UNSENT open()has not been called yet.
1 OPENED send()has not been called yet.
2 HEADERS_RECEIVED send() has been called, and headers and status are available.
3 LOADING Downloading; responseText holds partial data.
4 DONE The operation is complete.
這似乎表明,HEADERS_RECEIVED
將可在將整個文件下載,特別是在長傳遞。然而,在我的測試中,雖然事件按此順序觸發,但HEADERS_RECEIVED
和LOADING
幾乎與DONE
事件同時發生。
這是一個說明我的問題的基本示例。 OPENED
事件立即觸發,但HEADERS_RECEIVED
,LOADING
和DONE
都等待5秒鐘。我在Firefox和Chrome的本地Apache 2.4服務器上使用PHP 5.5運行此測試。
的JavaScript:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
console.log("readyState:", xmlhttp.readyState);
};
xmlhttp.open("GET", "handler.php", true);
xmlhttp.send();
handler.php:
<?php
header('Content-Type: text/plain');
echo "start\n";
sleep(5);
echo "end\n";
它似乎得到頭的唯一途徑之前內容是先做出HEAD
請求,那麼完整的請求。這是預期的行爲還是我錯過了什麼?
UPDATE:
使用符號鏈接通過較慢的網絡共享一個1GB的文件,或該輸出輸出顯着量的(下面的例子)不觸發HEADERS_RECEIVED
越早的PHP文件。雖然這似乎有點不可靠。我曾嘗試在sleep
之前使用PHP的flush
函數,但它沒有幫助。
<?php
header('Content-Type: text/plain');
echo "start\n";
$i = 10000000;
while($i--){
echo "1\n";
}
echo "end\n";
有沒有一種方法可靠地發送標題,而無需等待內容發送?
你似乎在做某事。查看我的更新。 – 2014-11-01 02:33:45
我相信PHP中的輸出緩衝區只會用'ob_flush()'刷新,我不相信'flush()'會這樣做。嘗試使用'ob_flush()'。 – AlpineCoder 2014-11-01 14:04:45
有趣。我的理解是,'ob_flush'只有在你以編程方式使用'ob_start'時纔是必要的,但事實證明PHP可以(總是)自動創建一個輸出緩衝級別。看起來你可以通過調用'ob_get_level'來檢測它是否爲非零。 'ob_flush'本身是不夠的。看起來你必須首先調用'ob_flush',然後_then_'flush'來首先刷新內部緩衝區,然後發送給客戶端。這使事情更加複雜,但感謝您的幫助! – 2014-11-01 15:21:08