According to MDN,XMLHttpRequest
readyState
事件会触发5个事件,如下所示。
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
请求,然后是完整请求。这是预期的行为,还是我错过了什么?
更新
使用通过慢速网络共享符号链接的1GB文件或输出大量输出的PHP文件(例如下面的代码)会更快地触发HEADERS_RECEIVED
。但这似乎有点不可靠。我在sleep
之前尝试过使用PHP的flush
功能,但它没有帮助。
<?php
header( 'Content-Type: text/plain' );
echo "start\n";
$i = 10000000;
while( $i-- ){
echo "1\n";
}
echo "end\n";
有没有办法可靠地发送标头而无需等待内容发送?
答案 0 :(得分:1)
至少在你的例子中,我猜测PHP实际上并没有冲洗缓冲区(因此发送标题)直到睡眠之后,但我不确定是否如果您使用实际文件下载遇到它,我会解释这种行为。