如何提前关闭连接?

2022-08-30 07:28:04

我正在尝试执行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.' );

?>

答案 1

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

据推测,它需要的不仅仅是发送一个关闭的标头。


OP然后确认:是的,这确实做到了:指向用户注释#71172(2006年11月)复制在这里:

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

sts at mail dot xubion dot hu 发布了原始解决方案:

<?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
  • 火狐浏览器 1.81

后来在2010年7月的相关答案北极火灾中,又链接了两个用户注释,它们是上述一个的后续:


答案 2

有必要发送以下 2 个标头:

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将不起作用,因为输出的实际大小已更改,并且内容长度不再准确。禁用特定脚本的 gzip 压缩。

有关更多详细信息,请访问 http://www.zulius.com/how-to/close-browser-connection-continue-execution


推荐