浏览器在调用abort后仍等待ajax请求完成(jQuery)

31

我有一些(可能)长时间运行的ajax调用,如果用户导航到另一个页面,我想要中止这些调用。以下jQuery代码在导航离开页面时对所有挂起的XMLHttpRequest对象调用abort:

$.ajaxSetup({
    beforeSend: function(xhr) {
        $(window).bind('beforeunload', function() {
            xhr.abort();
        });
    }
});

在一个测试用例中,我强制让服务器端的操作等待10秒钟。使用Firebug,我确认了上述代码确实会导致当我点击页面上的任何链接时所有未决的ajax调用立即停止。但是,浏览器仍然要等待完整的10秒钟才能进入下一个页面。IE似乎表现出相同的行为。这是一种已知的浏览器行为吗?在这种情况下,有什么我可以做来允许用户立即离开页面吗?提前感谢。


Ajax调用是什么样子的? - epascarello
7个回答

32

感谢您的回复!事实证明我完全错了,这不是浏览器问题,而是服务器问题。ASP.NET序列化需要会话状态的相同会话请求,因此在这种情况下,直到ajax-initiated请求完成,下一页才开始在服务器上处理。

不幸的是,在这种情况下,会话状态在响应ajax调用的http处理程序中是必需的。但只读访问就足够了,所以通过使用IReadOnlySessionState标记处理程序,而不是IRequiresSessionState,可以避免会话锁定,从而解决了该问题。

希望这些信息对其他人有用。


你有没有更详细的参考资料可以解释这个问题? - Phil
@Phil,我在这里找到了有关ASP.NET问题的更多信息:http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/ - John Washam
1
如果我们使用会话状态(读取和编辑),是否有可能避免等待? - VikkyB

13

关于托德自己对这个问题的回答...

我最近用PHP遇到了同样的问题,相同的解决方案适用。但是我需要将信息保存在会话中。对于PHP开发人员,您可以调用session_write_close()在请求过程中关闭并写出您的会话。这将释放会话以供其他请求使用。


@acdameli 我应该在导致问题的函数中调用session_write_close(),还是在稍后调用的函数中调用? - Deepanshu Goyal

3

您可能需要检查abort()方法的一个奇怪副作用。

当使用abort()方法时,在Explorer和Mozilla中会触发readystatechange事件。更糟糕的是,readyState = 4,这意味着平均xmlhttp脚本认为数据已正确加载。这可能会产生非常奇怪的效果。

详细信息请参阅:

http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_a_1.html


2

您确定正在使用异步请求吗?如果浏览器在整个请求期间都被阻止,则表示您正在使用同步请求(async参数为false)


服务器实际上正在阻塞导航,因为它想要导航到的页面使用与正在运行并保持会话的 AJAX 请求相同的会话。 - grantwparks

1

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。仅有链接的答案如果链接页面发生更改可能会变得无效。 - Rajesh

1

服务器问题也出现在我正在使用的Apache/Php服务器上。在一个不需要它(AJAX)的脚本上删除了session_start,一切都按预期工作。 感谢Todd指出了类似的问题!


0

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