不等待AJAX请求的响应


Not Waiting for Response from an AJAX Request

假设我从jQuery向后端PHP脚本发出AJAX HTTP请求。发出请求后,PHP脚本开始运行并发挥其魔力。假设我随后切换到另一个网站,远离发出原始AJAX请求的网站。同样,我在PHP脚本完成并有时间执行HTTP响应之前执行此操作。PHP脚本完成运行和做它的事情,即使我已经切换到另一个网站之前,我得到HTTP响应?

所以顺序是这样的

  • 我在网站www.xyz.com
  • 我有一个jQuery处理程序启动一个AJAX请求blah.php
  • blah.php启动
  • 在没有等待blah.php的响应后,我马上去了网站www.abc.com

blah.php怎么了?处决还在继续吗?它停止了吗?我的意思是它没有机会回应所以。

这可能取决于您的服务器配置,但是通常情况下,尽管HTTP连接已关闭,脚本仍将继续执行

我已经测试了Apache 2 + PHP 5作为mod_php。我希望PHP的行为与CGI和其他web服务器类似,但不确定。

确定您的配置的最佳方法是,正如@tdammers建议的那样:设置一个像下面这样的测试脚本并监视日志。

<?php
error_log('Test script started.');
for ($i = 1; $i < 13; $i++) {
    sleep(10);
    error_log('Test script got to ' . (10 * $i) . ' seconds.');
}
error_log('Test script got to the end.');
?>

访问这个脚本(在/test.php或其他位置),然后在您得到任何结果之前,在浏览器上点击停止。这相当于在XHR返回之前离开。您甚至可以将它作为XHR的目标,然后导航到别处。

然后检查你的错误日志:你应该有一个开始,然后消息每10秒,持续两分钟和结束。如果您也想测试的话,可以修改$i的高值,以确保脚本达到预期的最大执行时间。

你不需要使用error_log() -你可以写一个文件,或者在服务器上做一些其他的持久的改变,可以检查而不需要保持客户端连接打开。

由于max_execution_time php.ini指令,脚本执行时间可能会在此之前停止-但在任何情况下,这应该与web服务器超时时不同。

Try ignore_user_abort(true);

ignore_user_abort(true);

它不应该中止你的代码的处理

你可能想看看这个问题的答案。基本上,当您对调用exec()函数的php函数进行ajax调用时(如该问题的答案所示),您将几乎立即获得ajax响应,因为php函数实际上不需要处理任何内容。这样,用户离开页面就无关紧要了。下面是一个小例子:

ajax调用在html文件:$.ajax({url: 'blah.php'});

blah.php file: exec('bash -c "exec nohup setsid php really_slow_script.php > /dev/null 2>&1 &"');

最后在really_slow_script.php中,只包含你想要运行的实际代码。

我成功地使用了这种逻辑,允许用户从他们在我网站上的帐户上传已经上传的视频到youtube。(视频必须发送到youtube,由于视频通常是大文件,我不希望用户在视频上传到youtube时不得不等待)

导航离开将触发服务器上的断开连接消息。其含义完全取决于您的服务器被配置为做什么。

默认情况下,服务器将被设置为断开连接不会中断程序运行的方式。但是,可以这样做:用户断开连接将触发已经注册到register_shutdown_function的函数,垃圾收集将发生,脚本将终止。

因为它是可以在几个不同的地方配置的东西,它可能是最简单的运行一个测试,但这是一个php.ini指令。如果你想在全局级别上配置它,你可以在php.ini中设置ignore_user_abort = Off。如果您希望在特定于站点的级别上这样做,您可以在当前站点的父目录的htaccess中使用php_value ignore_user_abort off。否则,您可以使用ignore_user_abort(false);

当然,在共享服务器上不能保证你有htaccess或php.ini的控制权,所以你可能只需要使用ignore_user_abort(false);