Javascript Chrome 中的 window.onbeforeunload ajax 请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4945932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
window.onbeforeunload ajax request in Chrome
提问by lang2
I have a web page that handles remote control of a machine through Ajax. When user navigate away from the page, I'd like to automatically disconnect from the machine. So here is the code:
我有一个通过 Ajax 处理机器远程控制的网页。当用户离开页面时,我想自动断开与机器的连接。所以这里是代码:
window.onbeforeunload = function () {
bas_disconnect_only();
}
The disconnection function simply send a HTTP GET request to a PHP server side script, which does the actual work of disconnecting:
断开连接函数只是向 PHP 服务器端脚本发送一个 HTTP GET 请求,它完成断开连接的实际工作:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
});
}
This works fine in FireFox. But with Chrome, the ajax request is not sent at all. There is a unacceptable workaround: adding alert to the callback function:
这在 FireFox 中运行良好。但是对于 Chrome,根本不发送 ajax 请求。有一个不可接受的解决方法:向回调函数添加警报:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
alert("You're been automatically disconnected.");
});
}
After adding the alert call, the request would be sent successfully. But as you can see, it's not really a work around at all.
添加警报调用后,请求将成功发送。但正如你所看到的,这根本不是一个解决办法。
Could somebody tell me if this is achievable with Chrome? What I'm doing looks completely legit to me.
有人能告诉我这是否可以用 Chrome 实现?我正在做的事情在我看来完全合法。
Thanks,
谢谢,
采纳答案by Garry English
I was having the same problem, where Chrome was not sending the AJAX request to the server in the window.unload event.
我遇到了同样的问题,Chrome 没有在 window.unload 事件中向服务器发送 AJAX 请求。
I was only able to get it to work if the request was synchronous. I was able to do this with Jquery and setting the asyncproperty to false:
如果请求是同步的,我只能让它工作。我能够使用 Jquery 做到这一点并将async属性设置为false:
$(window).unload(function () {
$.ajax({
type: 'GET',
async: false,
url: 'SomeUrl.com?id=123'
});
});
The above code is working for me in IE9, Chrome 19.0.1084.52 m, and Firefox 12.
上面的代码在 IE9、Chrome 19.0.1084.52 m 和 Firefox 12 中对我有用。
回答by Mohoch
This is relevant for newer versions of Chrome.
这与较新版本的 Chrome 相关。
Like @Garry English said, sending an async
request during page onunload
will not work, as the browser will kill the thread before sending the request. Sending a sync
request should work though.
就像@Garry English说的那样,async
在页面期间发送请求是onunload
行不通的,因为浏览器会在发送请求之前杀死线程。发送sync
请求应该可以工作。
This was right until version 29 of Chrome, but on Chrome V 30 it suddenly stopped working as stated here.
这一直到 Chrome 29 版,但在 Chrome V 30 上它突然停止工作,如此处所述。
It appears that the only way of doing this today is by using the onbeforeunload
event as suggested here.
看来今天这样做的唯一方法是使用此处建议的onbeforeunload
事件。
BUT NOTE: other browsers will not let you send Ajax requests in the onbeforeunload event at all. so what you will have to do is perform the action in both unload and beforeunload, and check whether it had already taken place.
但请注意:其他浏览器根本不会让您在 onbeforeunload 事件中发送 Ajax 请求。所以你需要做的是在卸载和卸载之前执行操作,并检查它是否已经发生。
Something like this:
像这样的东西:
var _wasPageCleanedUp = false;
function pageCleanup()
{
if (!_wasPageCleanedUp)
{
$.ajax({
type: 'GET',
async: false,
url: 'SomeUrl.com/PageCleanup?id=123',
success: function ()
{
_wasPageCleanedUp = true;
}
});
}
}
$(window).on('beforeunload', function ()
{
//this will work only for Chrome
pageCleanup();
});
$(window).on("unload", function ()
{
//this will work for other browsers
pageCleanup();
});
回答by Sparky
Checkout the Navigator.sendBeacon()method that has been built for this purpose.
检查为此目的构建的Navigator.sendBeacon()方法。
The MDN page says:
MDN 页面说:
The navigator.sendBeacon() method can be used to asynchronously transfer small HTTP data from the User Agent to a web server.
navigator.sendBeacon() 方法可用于将小型 HTTP 数据从用户代理异步传输到 Web 服务器。
This method addresses the needs of analytics and diagnostics code that typically attempt to send data to a web server prior to the unloading of the document. Sending the data any sooner may result in a missed opportunity to gather data. However, ensuring that the data has been sent during the unloading of a document is something that has traditionally been difficult for developers.
此方法解决了分析和诊断代码的需求,这些代码通常会在卸载文档之前尝试将数据发送到 Web 服务器。过早发送数据可能会导致错失收集数据的机会。但是,确保在卸载文档期间发送数据对于开发人员来说历来是困难的。
This is a relatively newer API and doesn't seems to be supported by IE yet.
这是一个相对较新的 API,IE 似乎还不支持。
回答by Metod Medja
Try creating a variable (Boolean preferably) and making it change once you get a response from the Ajax call. And put the bas_disconnect_only()
function inside a while loop.
I also had a problem like this once. I think this happens because Chrome doesn't wait for the Ajax call. I don't know how I fixed it and I haven't tried this code out so I don't know if it works. Here is an example of this:
尝试创建一个变量(最好是布尔值),并在收到 Ajax 调用的响应后更改它。并将该bas_disconnect_only()
函数放入一个 while 循环中。我也遇到过这样的问题。我认为这是因为 Chrome 不等待 Ajax 调用。我不知道我是如何修复它的,我还没有尝试过这段代码,所以我不知道它是否有效。这是一个例子:
var has_disconnected = false;
window.onbeforeunload = function () {
while (!has_disconnected) {
bas_disconnect_only();
// This doesn't have to be here but it doesn't hurt to add it:
return true;
}
}
And inside the bas_send_request()
function (xmlhttpis the HTTP request):
在bas_send_request()
函数内部(xmlhttp是 HTTP 请求):
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
has_disconnected = true;
}
Good luck and I hope this helps.
祝你好运,我希望这会有所帮助。
回答by GyuHyeon Choi
Synchronous XMLHttpRequest
has been deprecated (Synchronous and asynchronous requests). Therefore, jQuery.ajax()
's async: false
option has also been deprecated.
同步XMLHttpRequest
已被弃用(同步和异步请求)。因此,jQuery.ajax()
的async: false
选项也已被弃用。
It seems impossible (or very difficult) to use synchronous requests during beforeunload
or unload
(Ajax Synchronous Request Failing in Chrome). So it is recommended to use sendBeacon
and I definitely agree!
在beforeunload
或unload
(Chrome 中的 Ajax 同步请求失败)期间使用同步请求似乎是不可能的(或非常困难的)。所以推荐使用sendBeacon
,我绝对同意!
Simply:
简单地:
window.addEventListener('beforeunload', function (event) { // or 'unload'
navigator.sendBeacon(URL, JSON.stringify({...}));
// more safely (optional...?)
var until = new Date().getTime() + 1000;
while (new Date().getTime() < until);
});
回答by sNICkerssss
I had to track any cases when user leave page and send ajax request to backend.
当用户离开页面并将ajax请求发送到后端时,我必须跟踪任何情况。
var onLeavePage = function() {
$.ajax({
type: 'GET',
async: false,
data: {val1: 11, val2: 22},
url: backend_url
});
};
/**
* Track user action: click url on page; close browser tab; click back/forward buttons in browser
*/
var is_mobile_or_tablet_device = some_function_to_detect();
var event_name_leave_page = (is_mobile_or_tablet_device) ? 'pagehide' : 'beforeunload';
window.addEventListener(event_name_leave_page, onLeavePage);
/**
* Track user action when browser tab leave focus: click url on page with target="_blank"; user open new tab in browser; blur browser window etc.
*/
(/*@cc_on!@*/false) ? // check for Internet Explorer
document.onfocusout = onLeavePage :
window.onblur = onLeavePage;
Be aware that event "pagehide" fire in desktop browser, but it doesn't fire when user click back/forward buttons in browser (test in latest current version of Mozilla Firefox).
请注意,桌面浏览器中会触发“pagehide”事件,但当用户单击浏览器中的后退/前进按钮时,它不会触发(在最新版本的 Mozilla Firefox 中测试)。
回答by Xabier Aparicio Mu?oa
I've been searching for a way in which leaving the page is detected with AJAXrequest. It worked like every time I use it, and check it with MySQL. This is the code (worked in Google Chrome):
我一直在寻找一种通过AJAX请求检测离开页面的方法。每次我使用它时它都有效,并使用 MySQL 进行检查。这是代码(在Google Chrome 中工作):
$(window).on("beforeunload", function () {
$.ajax({
type: 'POST',
url: 'Cierre_unload.php',
success: function () {
}
})
})