【发布时间】:2014-12-28 09:58:53
【问题描述】:
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";
有没有办法在不等待内容发送的情况下可靠地发送标头?
【问题讨论】:
标签: javascript php ajax apache xmlhttprequest