我有一个网页,通过Ajax处理机器的远程控制。当用户离开页面时,我想自动断开与机器的连接。所以这是代码:
window.onbeforeunload = function () {
bas_disconnect_only();
}
断开连接功能只是向PHP服务器端脚本发送HTTP GET请求,该脚本执行断开连接的实际工作:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
});
}
这在FireFox中运行良好。但是使用Chrome时,根本不会发送ajax请求。有一种不可接受的解决方法:向回调函数添加警报:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
alert("You're been automatically disconnected.");
});
}
添加警报呼叫后,请求将成功发送。但正如你所看到的,它根本不是一个解决方法。
有人可以告诉我这是否可以通过Chrome实现吗?我正在做的事情看起来完全合法。
谢谢,
答案 0 :(得分:64)
这与较新版本的Chrome相关。
与@Garry English said一样,在页面async
期间发送onunload
请求将无效,因为浏览器会在发送请求之前终止线程。发送sync
请求应该可以正常工作。
这是直到Chrome第29版,但在Chrome V 30上它突然停止工作as stated here。
今天看来这样做的唯一方法是使用onbeforeunload
事件as suggested here。
但是注意:其他浏览器根本不允许您在onbeforeunload事件中发送Ajax请求。所以你需要做的是在卸载和beforeunload中执行操作,并检查它是否已经发生。
这样的事情:
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();
});
答案 1 :(得分:40)
我遇到了同样的问题,Chrome没有在window.unload事件中向服务器发送AJAX请求。
如果请求是同步的,我只能让它工作。我能够使用Jquery并将异步属性设置为 false :
$(window).unload(function () {
$.ajax({
type: 'GET',
async: false,
url: 'SomeUrl.com?id=123'
});
});
以上代码适用于IE9,Chrome 19.0.1084.52 m和Firefox 12。
答案 2 :(得分:17)
签出为此目的而构建的Navigator.sendBeacon()方法。
MDN页面说:
navigator.sendBeacon()方法可以异步使用 将小型HTTP数据从用户代理传输到Web服务器。
此方法可满足分析和诊断代码的需求 通常尝试在卸载之前将数据发送到Web服务器 该文件。更快地发送数据可能会导致错过 收集数据的机会。但是,确保数据已经存在 在卸载文档期间发送的内容是有的 传统上开发人员很难。
这是一个相对较新的API,似乎还没有得到IE的支持。
答案 3 :(得分:3)
尝试创建变量(最好是布尔值)并在从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;
}
}
在bas_send_request()
函数内部( xmlhttp 是HTTP请求):
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
has_disconnected = true;
}
祝你好运,我希望这会有所帮助。
答案 4 :(得分:0)
我必须跟踪用户离开页面并将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;
请注意,事件“ pagehide”在桌面浏览器中触发,但是当用户在浏览器中单击“后退/前进”按钮时不会触发(在最新的Mozilla Firefox最新版本中进行测试)。
答案 5 :(得分:0)
我一直在寻找一种通过 AJAX 请求检测离开页面的方法。就像我每次使用它一样,并使用MySQL对其进行检查。这是代码(在 Google Chrome 中使用):
$(window).on("beforeunload", function () {
$.ajax({
type: 'POST',
url: 'Cierre_unload.php',
success: function () {
}
})
})
答案 6 :(得分:0)
不推荐使用同步XMLHttpRequest
(Synchronous and asynchronous requests)。因此,jQuery.ajax()
的{{1}}选项也已被弃用。
在async: false
或beforeunload
期间似乎不可能(或非常困难)使用同步请求
(Ajax Synchronous Request Failing in Chrome)。因此,建议使用sendBeacon
,我绝对同意!
简单地:
unload
答案 7 :(得分:0)
Try navigator.sendBeacon(...);
try {
// For Chrome, FF and Edge
navigator.sendBeacon(url, JSON.stringify(data));
}
catch (error)
{
console.log(error);
}
//For IE
var ua = window.navigator.userAgent;
var isIEBrowser = /MSIE|Trident/.test(ua);
if (isIEBrowser) {
$.ajax({
url: url,
type: 'Post',
.
.
.
});
}