一尘不染

如何提早关闭连接?

php

我正在尝试进行AJAX调用(通过JQuery),这将启动一个相当长的过程。我希望脚本仅发送一个指示进程已启动的响应,但是JQuery在PHP脚本运行完成之前不会返回响应。

我已经尝试过使用“关闭”标头(如下),以及输出缓冲了。似乎都不起作用。有什么猜想吗?还是我需要在JQuery中做这件事?

<?php

echo( "We'll email you as soon as this is done." );

header( "Connection: Close" );

// do some stuff that will take a while

mail( 'dude@thatplace.com', "okay I'm done", 'Yup, all done.' );

?>

阅读 265

收藏
2020-05-26

共1个答案

一尘不染

以下PHP手册页(包括用户注释)建议了有关如何在不结束PHP脚本的情况下关闭与浏览器的TCP连接的多种说明:

据说它比发送关闭标头还需要更多。


然后 OP确认:是的 ,这成功了: 指向复制在此处的用户注释#71172(2006年11月)

自[PHP]
4.1起,在保持php脚本运行的同时关闭用户浏览器连接一直是一个问题,当时该行为已register_shutdown_function()被修改为不会自动关闭用户连接。

邮件点xubion点hu的sts发表了原始解决方案:

<?php
header("Connection: close");
ob_start();
phpinfo();
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();
flush();
sleep(13);
error_log("do something in the background");
?>

其中,直到你代替工作正常phpinfo()进行echo('text I want user to see');在这种情况下,头永远不会发送!

解决方案是在发送标头信息之前显式关闭输出缓冲并清除缓冲区。例:

<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
// Do processing here
sleep(30);
echo('Text user will never see');
?>

刚刚花了3个小时试图弄清楚这个问题,希望对您有所帮助:)

经过测试:

  • IE 7.5730.11
  • Mozilla Firefox 1.81
2020-05-26