我正在尝试进行AJAX调用(通过JQuery),这将启动一个相当长的过程.我希望脚本只是发送一个响应,表明进程已经启动,但是在PHP脚本运行完毕之前,JQuery不会返回响应.
我用"关闭"标题(下面)尝试了这个,还有输出缓冲; 似乎都不起作用.任何猜测?或者这是我在JQuery中需要做的事情?
Joeri Sebrec.. 85
以下PHP手册页(包括用户注释)提供了有关如何在不结束PHP脚本的情况下关闭与浏览器的TCP连接的多条指令:
连接处理文档
据说它需要的不仅仅是发送一个关闭标题.
然后OP确认:是的,这就是诀窍: 指向用户注释#71172(2006年11月)复制到这里:
在保持php脚本运行的同时关闭用户浏览器连接一直是一个问题,因为[PHP] 4.1,当
register_shutdown_function()
修改了行为以便它不会自动关闭用户连接时.sts at mail dot xubion dot hu发布原始解决方案:
其中,直到你代替工作正常
phpinfo()
进行echo('text I want user to see');
在这种情况下,头永远不会发送!解决方案是在发送标头信息之前明确关闭输出缓冲并清除缓冲区.例:
只花了3个小时试图弄清楚这一个,希望它能帮助别人:)
测试中:
IE 7.5730.11
Mozilla Firefox 1.81
后来在2010年7月的一个相关答案中, Arctic Fire随后将另外两个用户注释与后续用户注释相关联:
连接处理用户注释#89177(2009年2月)
连接处理用户注释#93441(2009年9月)
是的,这就是诀窍:http://www.php.net/manual/en/features.connection-handling.php#71172 (7认同)
黑客和糟糕的Web浏览器仍然可以忽略连接关闭的HTTP标头,并获取其余的输出。确保接下来出现的内容不敏感。也许是ob_start(); 抑制一切:p (3认同)
添加fastcgi_finish_request(); 一直说要成功地关闭时,上述方法无效的连接.然而,在我的情况下,它阻止我的脚本执行持续,所以请谨慎使用. (3认同)
Timbo White.. 54
有必要发送这两个标题:
Connection: close Content-Length: n (n = size of output in bytes )
由于您需要知道输出的大小,因此您需要缓冲输出,然后将其刷新到浏览器:
// buffer all upcoming output ob_start(); echo "We'll email you as soon as this is done."; // get the size of the output $size = ob_get_length(); // send headers to tell the browser to close the connection header("Content-Length: $size"); header('Connection: close'); // flush all output ob_end_flush(); ob_flush(); flush(); // if you're using sessions, this prevents subsequent requests // from hanging while the background process executes if (session_id()) session_write_close(); /******** background process starts here ********/
此外,如果您的Web服务器在输出上使用自动gzip压缩(即带有mod_deflate的Apache),这将无法工作,因为输出的实际大小已更改,并且Content-Length不再准确.禁用gzip压缩特定脚本.
有关更多详细信息,请访问http://www.zulius.com/how-to/close-browser-connection-continue-execution
以下PHP手册页(包括用户注释)提供了有关如何在不结束PHP脚本的情况下关闭与浏览器的TCP连接的多条指令:
连接处理文档
据说它需要的不仅仅是发送一个关闭标题.
然后OP确认:是的,这就是诀窍: 指向用户注释#71172(2006年11月)复制到这里:
在保持php脚本运行的同时关闭用户浏览器连接一直是一个问题,因为[PHP] 4.1,当
register_shutdown_function()
修改了行为以便它不会自动关闭用户连接时.sts at mail dot xubion dot hu发布原始解决方案:
其中,直到你代替工作正常
phpinfo()
进行echo('text I want user to see');
在这种情况下,头永远不会发送!解决方案是在发送标头信息之前明确关闭输出缓冲并清除缓冲区.例:
只花了3个小时试图弄清楚这一个,希望它能帮助别人:)
测试中:
IE 7.5730.11
Mozilla Firefox 1.81
后来在2010年7月的一个相关答案中, Arctic Fire随后将另外两个用户注释与后续用户注释相关联:
连接处理用户注释#89177(2009年2月)
连接处理用户注释#93441(2009年9月)
有必要发送这两个标题:
Connection: close Content-Length: n (n = size of output in bytes )
由于您需要知道输出的大小,因此您需要缓冲输出,然后将其刷新到浏览器:
// buffer all upcoming output ob_start(); echo "We'll email you as soon as this is done."; // get the size of the output $size = ob_get_length(); // send headers to tell the browser to close the connection header("Content-Length: $size"); header('Connection: close'); // flush all output ob_end_flush(); ob_flush(); flush(); // if you're using sessions, this prevents subsequent requests // from hanging while the background process executes if (session_id()) session_write_close(); /******** background process starts here ********/
此外,如果您的Web服务器在输出上使用自动gzip压缩(即带有mod_deflate的Apache),这将无法工作,因为输出的实际大小已更改,并且Content-Length不再准确.禁用gzip压缩特定脚本.
有关更多详细信息,请访问http://www.zulius.com/how-to/close-browser-connection-continue-execution
您可以使用Fast-CGI和PHP-FPM来使用该fastcgi_end_request()
功能.通过这种方式,您可以在响应已发送到客户端时继续进行一些处理.
如何使用fastcgi_finish_request()的例子(2010年11月)
您可以在PHP手册中找到:FastCGI Process Manager(FPM) ; 但该功能并未在手册中进一步说明.这里摘自PHP-FPM:PHP FastCGI Process Manager Wiki:
适用范围:php功能类别:优化
此功能允许您加快某些php查询的实现.当脚本执行过程中的操作不影响服务器响应时,可以进行加速.例如,在页面形成并传递到Web服务器之后,可以在memcached中保存会话.fastcgi_finish_request()
是一个PHP功能,它会停止响应输出.Web服务器立即开始向客户端"缓慢而悲伤地"传输响应,并且php同时可以在查询的上下文中执行许多有用的操作,例如保存会话,转换下载的视频,处理各种统计等
fastcgi_finish_request()
可以调用执行关机功能.
完整版:
ignore_user_abort(true);//avoid apache to kill the php running ob_start();//start buffer output echo "show something to user"; session_write_close();//close session file on server side to avoid blocking other requests header("Content-Encoding: none");//send header to avoid the browser side to take content as gzip format header("Content-Length: ".ob_get_length());//send length header header("Connection: close");//or redirect to some url: header('Location: http://www.google.com'); ob_end_flush();flush();//really send content, can't change the order:1.ob buffer to normal buffer, 2.normal buffer to output //continue do something on server side ob_start(); sleep(5);//the user won't wait for the 5 seconds echo 'for diyism';//user can't see this file_put_contents('/tmp/process.log', ob_get_contents()); ob_end_clean();
更好的解决方案是派生后台进程。在unix / linux上是相当简单的:
/dev/null &"); ?>
您应该查看此问题以获取更好的示例:
PHP执行后台进程