【问题标题】:Need to keep ajax alive whilst php script is working需要在 php 脚本工作时保持 ajax 存活
【发布时间】:2015-06-22 16:17:11
【问题描述】:

希望有人可以帮助我。

我有一个将变量传递给 php 文件 (thumbs.php) 的 ajax 脚本 (index.php)。

php 文件从原始文件生成缩略图并将它们存储在服务器上。此过程可能需要相当长的时间才能完成(最多 10 分钟)。

在此过程进行的同时,我有一个叠加层告诉用户等待。这一切都很好。

但是,一旦 php 脚本返回“真”(即完成),覆盖应该消失。

问题: 覆盖不会消失。我可以在 Firebug 中看到 index.php 不等待 thumbs.php 的响应。它总是在 1-1.5 分钟左右超时。 我不知何故需要保持连接打开。

... more code here
    (function worker() {
        $.ajax({
            url: 'thumbs.php',
            type: 'POST',
            dataType: 'json',
            data: dataPass,
            beforeSend: function(){
                $('.overlay').show();
                $('.result').show();
                $('.resultText').html("<center>Please wait whilst we create thumbnail images for this folder.<br><br>This is a one time operation.<br><br>Please be patient.</center>");
            },
            success: function(data){
                $.each(data, function(i, obj){
                alert(obj.count); // THIS should return true when finished
                });
            },
            complete: function() {
                $('.overlay').hide();
                $('.result').hide();
            }
        });
    })();       
...more code here   

编辑:

好吧,我还有一点!

脚本现在可以正常循环,但永远不会停止! clearTimeout(timer) 不清除,即使两个警报框显示相同的 id。

非常感谢您的帮助!

(function poll(){
var timer = 0;
var timer = setTimeout(function(){
alert("timer 1: " + timer);
$.ajax({
    url: 'thumbs.php',
    type: 'POST',
    dataType: 'json',
    data: dataPass,
    success: function(data){
        $.each(data,function(i,j){
            reply = j.count;
        });

        if(reply == 'true'){
            alert("timer 2: " + timer);
            clearTimeout(timer);
            $('.overlay').hide();
            $('.result').hide();
        }
    },
    complete: function(){
        poll();
    }
});
},3000);
})();

更多编辑:

嗯,我可以看到我的问题。这段代码

 if(reply == 'true'){
        alert("timer 2: " + timer);
        clearTimeout(timer);
        $('.overlay').hide();
        $('.result').hide();
    }

在 setTimeout 内运行,因此计时器永远不会被清除。因此,整个代码永远运行。解决办法是什么?

【问题讨论】:

  • 根据您使用的 jQuery 版本,您可能需要切换到 jqXHR.done()jqXHR.fail()jqXHR.always()

标签: jquery ajax loops settimeout cleartimeout


【解决方案1】:

您正在运行 PHP 的 max_execution_time 或您的 Web 服务器的请求超时,并且该进程可能在完成之前被终止。无论哪种方式,我都建议您考虑更改架构以实现一个简单的队列/调度器系统,该系统可以添加作业、检查作业状态并执行作业。然后,您的 ajax 可以使用 setInterval 每 10 秒轮询一次以询问“jobId 完成了吗?”并在答案为真时关闭覆盖。你真的不想让恶意的人堆积多个 10 分钟的工作。

【讨论】:

  • 此网页仅供我家人使用,并受密码保护。 php 脚本还会检查缩略图是否已经存在,如果存在,则返回“true”。整个过程在我自己的服务器上运行,并且我已经将 max_execution_time 设置为 12 分钟,这无论如何都不是问题(我不认为),因为即使我离开页面,thumbs.php 脚本也会继续生成缩略图。
  • 12 分钟的 max_execution_time 将允许 PHP 执行脚本 12 分钟。如果你是从命令行运行它,那么故事就结束了。由于您是从 Web 服务器运行它,因此如果运行时间过长,您的 Web 服务器仍会终止该进程。您是否注意到它是否处理了一些但不是全部的缩略图?对于 Apache,请参阅 httpd.apache.org/docs/2.0/mod/core.html#timeout
  • php 脚本运行良好。它产生所有的缩略图。这是 ajax 在 1-1.5 分钟后超时...
  • wait_timeout 如果您正在使用 mysql 做任何事情,也可能会参与其中。正如答案所述,我同意 - 发送工作,然后在循环中进行一些长时间轮询,看看你完成了吗?现在怎么样?仍在继续?好的,很酷!
【解决方案2】:

增加 PHP 超时限制应该可以解决这个问题。我的建议?不要那样做。有时(例如共享主机)你甚至不能,呵呵。

我建议在这里稍微改变一下方法。特别是,我的方法是对 PHP 函数进行一些轮询,以检查缩略图是否已经生成,并且仅在该函数返回 true 时中止“请等待屏幕”。

换句话说,您会收到一个定期(例如每 10 秒)触发的 Ajax 请求,询问此 PHP 函数是否完成缩略图处理,并根据结果保留或中止“请等待屏幕”。

也许有人想出了一个更复杂(但也更复杂)的解决方案,比如使用套接字或类似的东西,但我的建议对于这个用例来说似乎已经足够了。

编辑:我完全忘了提到,您需要异步的服务器端缩略图生成过程才能使此解决方案高效,这可能会导致您使用PHP threads。对于简单的用例,它们非常简单。

【讨论】:

  • 是的,我认为我需要一个定期触发的 ajax 请求。但是我该怎么做呢?
  • 将您的定期 Ajax 调用放在 setInterval 函数 (w3schools.com/jsref/met_win_setinterval.asp) 中,这应该是客户端所需的全部内容。对于服务器端,请简要阅读我在答案中链接的 PHP 线程,并创建此函数来检查缩略图过程是否完成。
  • lucasnadalutti:是的,我认为你是对的!这正是我所需要的。现在无法让它工作,因为它继续循环。如果我无法弄清楚,将很快发布我的代码。
  • 刚刚看到您更新的代码。我认为您的 poll() 电话应该在您的 if (reply == 'true') 声明中。你把它放在complete 回调中,所以它会一直运行,不管回复和Ajax调用是成功还是错误。
  • 抱歉,没用。我将 poll() 放在 if 函数中并删除了现在为空的完成,但脚本超时并且回复永远不会被执行。 @lucasnadalutti
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
相关资源
最近更新 更多