有些操作需要太多时间,导致Ajax请求超时。
如何完成响应请求,然后再继续该操作?
有些操作需要太多时间,导致Ajax请求超时。
如何完成响应请求,然后再继续该操作?
该ignore_user_abort
指令,以及ignore_user_abort
功能可能是你在找什么:它应该让你发送给浏览器的响应,并在此之后,仍然在服务器上运行一些计算。
本文对此你可能感兴趣的: 如何使用ignore_user_abort()做加工带外的 ; 引用:
编辑2010-03-22:移除链接(指着http:// ! waynepan.com/2007/10/11/ ! how-to-use-ignore_user_abort-to-do-process-out-of-band/
-删除空格和!
如果你想尝试),看到@Joel的评论之后。
基本上,当您使用
ignore_user_abort(true)
在你的PHP脚本,该脚本将继续即使用户按下ESC键运行或停止对他的浏览器。 你如何使用它?
其中一个用途是内容返回给用户,并允许在处理事情,不需要用户交互才能关闭连接。下面的示例发送出
$response
给用户,关闭连接(使浏览器的微调/加载条停止),然后执行do_function_that_takes_five_mins();
与给定的例子:
ignore_user_abort(true);
header("Connection: close");
header("Content-Length: " . mb_strlen($response));
echo $response;
flush();
do_function_that_takes_five_mins();
(还有更多我没有复制粘贴)
请注意,你的PHP脚本仍然以适合max_execution_time
和memory_limit
限制-这意味着你不应该使用这个对于花太多时间操作。
这也将使用一个Apache进程 - 这意味着你不应该有几十个是做在同一时间的页面。
不过,好的技巧,提升使用体验,我想;-)
生成一个后台进程,并返回后台进程的ID,这样用户就可以在以后通过一些秘密的网址查询。
排序取决于你试图完成什么。
就我而言,我需要做的一堆服务器端处理的,与被发送回浏览器的数据只有极小量 - 汇总信息真的。
我试图创建一个邮件发件人 - 发送一封电子邮件,以超过250人,但可能还有更多(取决于有多少人在系统中注册)。
PHP的邮件处理快,但对于大量的,不够快,所以它必然超时。 要解决这个问题,我需要推迟在服务器/ PHP端超时,并保持浏览器挂在直到所有数据汇总并显示出来。
我的解决方案 - 传情。
本质上,我给了用户一个消息,说明了一些初步统计(尝试发送这么多的电子邮件),创建2 DIV盒(一个用于当前状态信息,第二个为最后的总结信息),显示的页面页脚,开始加工,完成后,更新的摘要信息。 不言而喻,如下所示:
通过收集你的数据,你要去过程启动,并得到一些总结信息。 就我而言,我把电子邮件地址列表中,验证它们并计数它们。
然后显示“尝试”的信息:
echo "Message contents:";
echo "<blockquote>$msgsubject<p>$msgbody</blockquote><p> </p>";
echo "Attempting <strong>" . $num_rows . "</strong> email addresses.";
现在您可以创建状态/最终信息一些div:
<div id=content name=content>
<div id=progress name=progress style='border: black 1px solid; width: ".$boxwidth."px; height: 20px;'></div>
<br>
</div>
其中$ boxwidth是宽度您希望进度条被(后述)
请注意,他们基本上是空的 - 我们稍后将填补它们。
最后,通过显示页面的页脚填写页面的其余部分(在我来说,我只是“包括”相应的文件)。
现在,所有这仍然是挂在页面缓存,无论是在服务器上(如果PHP缓存)或浏览器(因为它没有被告知我们没有完成),所以让我们使其得到推动和/或者使用“忽略”,并从上面的“冲洗”显示:
ignore_user_abort(true);
flush();
现在,浏览器开始显示的东西,我们需要给用户看到的东西,所以这里的挑逗 - 我们将创建一个状态栏,我们将在内部DIV显示,并为外DIV最终消息。
因此,当你遍历你的数据,定期(我将离开“多久”你来弄清楚),输出如下:
set_time_limit (3);
...
(process your data here)
...
<script>document.getElementById('progress').innerHTML += "<img src='images/progress_red.gif' width: $width height=20 border=0>"</script>
flush();
这将从根本上叠起来的小的4x20 progress_red图像彼此相邻,使得它看起来是一个红条在屏幕上移动。 就我而言,我这样做100次的基础上,什么号码我目前正在加工出来的总数来处理的百分比。 在“参数或者set_time_limit”将增加3秒的现有限制,让你知道你的脚本将无法运行于PHP的时限墙。 根据需要调整3秒钟的应用程序。
即使页面在技术上是“完成”,JavaScript代码将更新DIV HTML和我们的进度条会“动”。
当一切完成后,我再有多少项目实际上进行了处理报告,并添加到外DIV HTML和完成该页面:
<script>document.getElementById('content').innerHTML += "Message was sent to $sentcnt people."</script>
因为它把所有它的资质满足(页面syntactially结束)浏览器是幸福的,用户将看到somethign发生一直到结束,服务器
我倾向于不使用JavaScript,如果我能帮助它,但在的情况下,没有花哨的东西,CSS通过JavaScript的正在做,所以这是非常简单和容易看到怎么回事,并在浏览器网站低开销。 它的功能相当顺利。
我不主张这是完美的,但一个简单的,低开销的解决方案,它为我工作,而无需创建cronjobs,额外的排队机制或二次加工。
你需要flush()
调用必须立即发送到浏览器的响应。