jQuery ajax php 长轮询

3

我一直在尝试让这个长轮询脚本工作,但是我一直卡住了。这一次,我的问题出在向服务器发送ajax请求上。提供数据的php脚本(使用循环和sleep运行长轮询)工作得非常好,但我的jQuery脚本却没有。

到目前为止,我已经尝试过使用普通的$.ajax()请求和$.post()请求到脚本,但是当我这样做时,整个脚本都会停止。实际上,脚本加载得很好,但页面显示它仍在加载中(使用 Google Chrome 时,它在屏幕底部显示“正在等待”栏)。在 php 脚本的 60 秒超时后,jQuery 脚本收到“false”,因为没有找到任何数据。然后脚本应该重新请求数据。

我的问题是:如何避免浏览器显示它正在后台加载某些内容?我的服务器是共享服务器,因此当涉及安装服务器端东西时,我没有权限,所以必须仅使用 JavaScript(jQuery)和 php 来解决这个问题。

编辑:刚在 Internet Explorer 中检查了我的脚本,似乎没有显示任何正在加载脚本的迹象,但在 Google Chrome 中仍然存在问题。

编辑 发布一些代码:

这是我的 javascript 文件:

if($("#interestboard"))
{
    var lasttime = $("#lasttime").val();
    var pollurl = $("#pollurl").val();
    lpStart();
}
function lpStart()
{
    $.ajax({
        type: "GET",
        url: pollurl+lasttime,
        async: true,
        cache: false,
        success:function(data)
        {
            alert(data);
        },
        error: function()
        {
            alert("Something went wrong");
        }
    });
}

当然,这段代码被包含在$(document).ready()中。
我的php脚本大致如下:
while(time()-$time<60)
    {
        $this->class = $class["id"];
        $this->orderBy("timestamp");
        $this->_extraConditions = "`timestamp`>'$lastTime' AND ";
        $result = $this->search();
        if($result)
            return $result;
        usleep(250000);
        clearstatcache();
    }

使用Firebug(在Google Chrome中)时,它仅显示已发出请求,但未在控制台中显示常规的GET字符串末尾的加载图标。在Firefox中,它也只显示正在等待请求(显示加载图标),但至少浏览器不会像页面正在加载一样进行操作。
谢谢...

你是否正在使用Firefox和Firebug?这将有助于告诉你发生了什么。你能发布一些代码吗? - Brad
刚刚编辑了原始帖子,加入了源代码和使用Firebug的简要描述结果。 - Simon
我现在已经让其中一部分工作起来了。如果我设置一个超时,在DOM加载完成两秒后调用lpStart()函数,Google Chrome就不会显示加载栏,但这会带来一个新问题。每当我停止请求(例如通过点击链接),错误事件就会被触发,并弹出一个告诉我“出了些问题”的警报(就像它应该做的那样)。在此之后,该网站将无法加载,直到请求超时时间到达为止。这只会在我使用同一浏览器(同一会话)时发生,而不是当我在电脑上遇到错误,然后在iPad上加载页面时。 - Simon
1个回答

3
我认为你应该阅读Chrome AJAX on page-load causes "busy cursor" to remain上的顶级评论 - 看起来这是特定于Google Chrome的问题,你需要等待在进行任何ajax调用之前加载所有内容。
编辑:只是一个建议 - 可能我错了:您不应使用GET请求在站点上执行任何大型/敏感操作,因为这可能导致对您的站点进行简单攻击。拥有/黑客某些高负载站点的任何人都可以将一个不可见的iframe插入到他们的页面中,以便访问该页面的任何用户将进行该GET请求,而不会意识到它 - 它可能会导致您的服务器崩溃/受损(因为成千上万的请求发送到您的服务器)。 大多数现代浏览器不会允许跨站点POST请求,因此应该是安全的。
编辑2:关于您的站点在中止脚本后仍然无法使用的情况:这很可能是由于会话引起的。标准会话行为只允许同时运行具有相同会话的一个php实例 - 所有其他请求将等待直到所有其他脚本中的会话关闭。您应该尽快在脚本中关闭会话,使用自定义会话处理程序以启用具有相同会话的多个请求(最可能这将非常丑陋),或检测用户中止以尽快在浏览器中关闭脚本。

我之前尝试过检测用户中止操作,但我在某个地方读到了一些关于会话存储目录权限的内容,这将不允许php脚本在ajax调用脚本时检测到用户中止操作。唯一的问题是我没有更改默认的会话存储目录。你知道我如何在php中检测ajax调用时的用户中止操作吗? - Simon
现在我已经解决了。结合了你提到的两个方法。我在 while 循环之前添加了 session_write_close();,然后在 while 循环结束时添加了 if(connection_aborted) break;。这样它就可以检测到脚本的中止,并且一切都按照预期工作 :-) - Simon
我很高兴能够帮忙。但是你关于AJAX调用的信息是错误的:Web服务器无法检测用户是使用AJAX调用还是仅仅是页面请求(有时可以,但不是非常可靠):它们都是简单的HTTP请求(甚至可以在Firebug中查看请求并进行比较)。 AJAX不是什么新技术 - 它已经被使用了很长时间(使用iframes),我们通过XMLHttpRequest对象(或类似对象)得到的唯一新东西是更好地控制此请求中正在发生的事情。 - XzKto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接