窗口卸载时Ajax请求失败

时间:2013-12-05 10:17:57

标签: javascript jquery ajax http cors

我有一个场景,我需要在离开页面时发出跨域请求。端点配置了所有正确的CORS头。

这是请求:

$.ajax({
    type: "POST",
    url: URL,
    data: {
        // some stuff
    },
    async: false
});

按原样进行测试时,效果很好。当我尝试从unload处理程序触发此请求时:

$(window).unload(function() {
    // same as above
});

间歇失败。在它失败的情况下,我得到了这个堆栈跟踪:

Error: A network error occurred.
    at Object.x.ajaxTransport.x.support.cors.e.crossDomain.send (http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:6:9344)
    at Function.x.extend.ajax (http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:6:4804)
    at http://my.web.site.com/main.js:129:11
    at x.event.dispatch (http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:5:10006)
    at x.event.add.y.handle (http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:5:6789)

使用jQuery DOMException和错误代码19。

这里发生了什么?看起来这里有一些我不知道的竞争条件,但除了将请求设置为同步之外,我不确定我还能做什么。

2 个答案:

答案 0 :(得分:1)

您根本无法依赖卸载处理程序。可能是jQuery的实现或本地onbeforeunload。 (也许onbeforeunload会比jQuery的实现更好)
用户可以通过多种方式离开页面(崩溃,ALT + F4,关闭标签......)。

大多数浏览器都没有等待足够长的时间,因此大多数情况下您的异步请求都会失败。

你应该重新考虑你的设计。

答案 1 :(得分:0)

我最终使用了beforeunload事件:

$(window).on('beforeunload' function() {
    // same code
});

适用于所有现代浏览器。 beforeunload事件行为是一致的,只要请求是同步发送的,事件执行 - 以及窗口卸载 - 就会暂停。

这是确切的事件服务,例如Gmail,Facebook甚至Stack Overflow用于确认用户是否真的有兴趣在行动过程中离开页面。