问候家伙,
我正在研究我的php框架。它有一个响应管理器来包装php的头文件,cookie和缓冲区函数。我用它将结果页面发送给用户。
但是,即使页面标题和内容已经使用ob_start发送 - > ob_end_flush - >刷新,浏览器仍然挂起并等待脚本完成。
当我想做一些缓慢的工作,如更新当前用户的会话或只是发送邮件或上传某些内容时,它会导致问题。用户必须等到一切都完成,即使他们已经拥有包括标题的整个页面。
我想知道的是,如何让浏览器知道页面已完全加载,所以它现在可以显示页面?
谢谢!
////////////////////////////废弃的解决方案///////////////// ///////////
废弃的解决方案1
过去,我通常使用ob_start - >的组合。 ob_end_flush - > ob_flush - >刷新修复这个问题,似乎会这样:
function send($content) {
ob_start();
echo $content;
ob_end_flush();
ob_flush();
flush();
return true;
}
但是 ob_flush会抛出一个E_NOTICE,说它有“没有要冲洗的缓冲区”。我不想通过静音这个E_NOTICE来解决这个问题(,事实上,在我的框架中,没有办法将任何错误静音)。所以这不是解决这个问题的方法。
弃置解决方案2
我也尝试在发送内容后关闭连接,代码会这样:
function send($content) {
ob_start();
header('Connection: close');
echo $content;
ob_end_flush();
flush();
return true;
}
它可以解决任何错误的问题,但它带来了另一个问题:看到客户端的连接将在收到页面后关闭,当他们想要打开另一个页面时,他们必须重新连接。这将在网络上产生额外负载。
弃置解决方案3
是的,有些人建议我使用fastcgi,并使用fastcgi_finish_request();但我想让我的代码在环境之间更加兼容,所以它实际上不是一个选项。
答案 0 :(得分:0)
在 IIS 上,您无法在fastcgi
完成之前断开连接。您需要使用fascgi_finish_request()^
手动强制完成当前CGI
。
在 Apache 上,您可以使用Content-Length: 0
redirect trick^,但效果很好但不适用于IIS (至少不符合我的经验)。
PS :并确保执行ignore_user_abort(true)
并在任何这些之前延长运行时限制set_time_limit(0)
(infinte)以防止PHP从客户端关闭连接时关闭。
PPS :发送页面后运行的任务应进入 cronjobs 。这是更清洁的做事方式。