在返回 AJAX 响应之前阻止 Web 浏览器关闭 [重复]
Posted
技术标签:
【中文标题】在返回 AJAX 响应之前阻止 Web 浏览器关闭 [重复]【英文标题】:Preventing web browser from closing until AJAX response is returned [duplicate] 【发布时间】:2012-02-03 07:31:55 【问题描述】:我有一个在网络浏览器中运行的游戏(作为插件),我想做的是:
检测用户是否决定关闭浏览器(Alt+F4、点击“X”按钮等)
当我们调用我们的网络服务以记录用户已关闭浏览器时,防止浏览器关闭
一旦我们收到来自 Web 服务的响应,释放锁定并允许浏览器按请求关闭。
我们想要这样做的主要原因是我们遇到了一些并发问题,并且通过我们的日志,我们希望将退出/关闭浏览器的人与插件崩溃的真实实例隔离开来。
我考虑过用 JQuery 来做这件事(为了 X-Browser 的兼容性 - Opera 不能工作,但幸运的是我们在 Opera 上没有任何用户):
$(window).bind('beforeunload', function(e)
e.preventDefault();
// make AJAX call
);
问题在于,这会向用户显示一个确认对话框(“您确定要离开此页面吗”),用户可能会在发送 AJAX 调用之前确认该对话框。
所以问题是,有没有办法阻止浏览器在收到响应之前关闭?当页面更改时,'beforeunload' 也会触发 - 有没有办法区分点击链接和实际点击关闭?
感谢您对此的任何帮助!
【问题讨论】:
只是出于好奇......如果你交换“preventDefault”和“make ajax call”部分有什么区别吗? 【参考方案1】:避免关闭浏览器窗口是一件棘手的事情。实际上,除了从onbeforeunload
事件中返回非undefined
值之外,没有其他方法可以做到这一点,就像你描述的那样。
我可以提出一个可能的建议,即在onbeforeunload
事件中创建一个同步 ajax 请求。比如
window.onbeforeunload = function()
$.ajax(
url: '/foo',
type: 'GET',
async: false,
timeout: 4000
);
;
理论上,这将阻止浏览器最多 4 秒。实际上,浏览器会以不同的方式处理这一点。例如,Firefox(我在 9 上测试过)确实不会立即关闭窗口,但它也不尊重那里的超时值。我猜在取消请求和关闭窗口/选项卡之前,内部最多有 2 秒。不过,我想这在大多数情况下应该足够了。
您的另一个问题(如何区分单击链接)相当简单。如上所述,onbeforeunload
查看从其事件处理程序返回的内容。所以让我们假设我们的应用程序有一个 global 变量,我们可以做类似
var globalIndicator = true;
// ... lots of code
window.onbeforeunload = function()
return globalIndicator;
;
此时,当窗口/选项卡即将关闭时,我们总会收到一个确认对话框。如果我们想避免任何锚点点击,我们可以像这样修补它
$( 'a[href^=http]' ).on('click', function()
globalIndicator = undefined;
);
【讨论】:
感谢安德烈亚斯的意见;所以实际上没有办法阻止浏览器在收到响应之前关闭……问题是播放器的连接速度是否很慢; 2 秒可能不足以拨打电话。感谢您对区分单击链接的解释 - 最有帮助 如果您考虑如何使用它,很明显没有浏览器会允许页面在关闭之前任意长时间阻塞。如果可能的话,某人可以制作一个用户永远无法关闭的弹出式广告。【参考方案2】:至于您问题的第一部分,除了使用window.onbeforeunload
之外,没有可靠的方法可以防止浏览器关闭。浏览器是为用户服务的,如果用户选择关闭他的浏览器,它就会这样做。
对于第二个问题,通过 jQuery 将点击链接与触发 onbeforeunload
事件的其他事件区分开来相当容易:
$('a').click(function(e) ...);
例如,您可以使用它来确保点击不会触发unbeforeunload
:
$('a').click(function(e) window.onbeforeunload = null);
【讨论】:
【参考方案3】:您可以使用以下代码来防止浏览器关闭:-
window.onbeforeunload = function()
//Your code goes here.
return "";
现在,当用户关闭浏览器时,由于返回“”,他会收到确认对话框; & 等待用户的确认 & 这个等待时间使请求到达服务器。
【讨论】:
【参考方案4】:我很确定使用 javascript 不可能实现您想要的。但是既然你有一个浏览器插件,你不应该能够检查你的插件对象是否被正确清理了吗?我不确定你使用的是 ActiveX、NPAPI 还是 Firebreath 之类的东西,但是这些框架都有生命周期方法,在正常关闭的情况下会在你的插件上调用,所以你应该能够写一些东西到此时记录。如果插件崩溃,这些将不会被调用。
【讨论】:
我们无法可靠地从插件进行调用的事实是我们开始考虑从网络浏览器进行调用的原因。以上是关于在返回 AJAX 响应之前阻止 Web 浏览器关闭 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
来自 ASP NET Web API 的 CORS 阻止 Ajax POST 调用 - 对预检请求的响应未通过访问控制检查