在页面卸载前执行服务器API调用/页面卸载限制



以下代码用于在chrome中工作,但由于chrome最近的更改"页面取消中不允许同步XHR"而突然停止。Crome在2019年4月初的最新更新中,我认为Chrome 73.0.3683.103停止了这一功能,他们建议发送信标或获取keepalive。我会发布我尝试过的内容,这样可能会帮助其他人。

https://www.chromestatus.com/feature/4664843055398912

$(window).on('beforeunload', function (e) {
//ajax call used work in Chrome 
}

https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload

我知道有几个相关的帖子与同样的情况有关,但仍然找不到解决方案。我尝试了几种方法拨打服务器电话。

步骤1:

$(window).on('beforeunload', function (e) {
if (navigator.sendBeacon) {
navigator.sendBeacon('url', 'data');
} else {
$.ajax({
type: 'POST',
url: 'url',
data: null,
contentType: 'application/json;',
async: false
});
}
}

由于内容类型-应用程序json ,此操作不起作用

步骤2:

$(window).on('beforeunload', function (e) {
var data = { ajax_data: 22 };
var blob = new Blob([JSON.stringify(data)], {type : 'application/json'});
navigator.sendBeacon('url', blob);
}

此代码不起作用,因为sendBeacon只支持这些内容类型

  • 多部分/表单数据
  • 应用程序/x-www-form-urlencoded
  • text/plain

步骤3:

$(window).on('beforeunload', function (e) {
if (fetch) {
fetch(url, {
method: "POST", headers: { "Content-Type": "application/json" } 
}).then(function (response) {
console.log(response.statusText);
}).then(function (response) {
console.log(response.statusText);
});
return false;
} else {
$.ajax({
type: 'POST',
url: 'url',
data: null,
contentType: 'application/json;',
async: false
});
}
}

这个代码有效!。但仅当您单击页面上的链接或单击"注销"按钮时。当用户点击链接、注销、关闭选项卡和关闭浏览器时离开页面时,我需要使用这种服务器方法。

第4步:

$(window).on('beforeunload', function (e) {
e.stopPropagation();
e.preventDefault();
fetch('url', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); 
}

这将显示一个弹出窗口"离开网站?",我不想让用户显示任何弹出窗口。

步骤5:

$(window).on('beforeunload', function (e) {
setTimeout(function ()
{
fetch('url', { method: 'POST', headers: { 'Content-Type': 'application/json' } });        
}, 3000);
return false;
}

同样与步骤4相同,显示"离开站点弹出窗口">

现在我已经没有选择了,还没有找到解决方案。感谢您的帮助。在页面卸载之前,我需要一个服务器调用,点击链接,注销,关闭选项卡,关闭浏览器。如果放置断点,上面的代码将起作用,这意味着在页面卸载之前发送服务器调用需要一些时间延迟。如果用户没有看到任何弹出窗口,比如"离开网站?",我不介意超时

这是一个老问题,但您需要在beforeunload事件中将keepalive标志设置为true的情况下使用fetch:

fetch(url, {
method: "POST",
keepalive: true, 
headers: { 
"Content-Type": "application/json" 
}
});

sendBeacon的行为与文档声称的不同。在我的测试中,它不尊重请求体中Blob的MIME类型,即使Blob是"支持的"MIME类型。

请改用fetch。它使您能够更好地控制请求头,同时保证您的请求将像sendBeacon那样发出。

您可能还需要在页面正文中绑定beforeunload事件。jQuery绑定可能不适用于beforeunload。

最新更新