window.onbeforeun在Chrome中加载ajax请求

lan*_*ng2 47 javascript ajax google-chrome

我有一个网页,通过Ajax处理机器的远程控制.当用户离开页面时,我想自动断开与机器的连接.所以这是代码:

window.onbeforeunload = function () {
  bas_disconnect_only();
}
Run Code Online (Sandbox Code Playgroud)

断开连接函数只是向PHP服务器端脚本发送HTTP GET请求,该脚本执行断开连接的实际工作:

function bas_disconnect_only () {
   var xhr = bas_send_request("req=10", function () {
   });
}
Run Code Online (Sandbox Code Playgroud)

这在FireFox中运行良好.但是使用Chrome时,根本不会发送ajax请求.有一种不可接受的解决方法:向回调函数添加警报:

function bas_disconnect_only () {
   var xhr = bas_send_request("req=10", function () {
     alert("You're been automatically disconnected.");
   });
}
Run Code Online (Sandbox Code Playgroud)

添加警报调用后,将成功发送请求.但正如你所看到的,它根本不是一个可行的工作.

有人可以告诉我这是否可以通过Chrome实现?我正在做的事情看起来完全合法.

谢谢,

Moh*_*och 68

这与较新版本的Chrome相关.

就像@Garry English 所说,async在页面中发送请求是onunload行不通的,因为浏览器会在发送请求之前终止线程.发送sync请求应该可行.

这是直到Chrome的第29版,但在Chrome V 30上它突然停止工作,如此处所述.

看来今天这样做的唯一方法是使用此处建议onbeforeunload事件.

但是注意:其他浏览器根本不允许您在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();
});
Run Code Online (Sandbox Code Playgroud)

  • 大.你可以写... .on('卸载前载',...并直接将函数打包在那里你不可以吗? (5认同)
  • Chrome 80 及更高版本不支持此功能。我刚刚遇到一个问题并降落在这里。https://developers.google.com/web/updates/2019/12/chrome-80-deps-rems (3认同)

Gar*_*ish 41

我遇到了同样的问题,Chrome没有在window.unload事件中向服务器发送AJAX请求.

如果请求是同步的,我只能让它工作.我能够使用Jquery并将async属性设置为false:

$(window).unload(function () {
   $.ajax({
     type: 'GET',
     async: false,
     url: 'SomeUrl.com?id=123'
   });
});
Run Code Online (Sandbox Code Playgroud)

以上代码适用于IE9,Chrome 19.0.1084.52 m和Firefox 12.

  • 请阅读以下@Mohoch给出的更新答案.它提供了反映浏览器更改的更新答案. (3认同)

Spa*_*rky 21

签出为此目的而构建的Navigator.sendBeacon()方法.

MDN页面说:

navigator.sendBeacon()方法可用于将小HTTP数据从用户代理异步传输到Web服务器.

此方法满足分析和诊断代码的需要,这些代码通常在卸载文档之前尝试将数据发送到Web服务器.更快地发送数据可能会导致错过收集数据的机会.但是,确保在卸载文档期间已经发送数据对于开发人员来说传统上是困难的.

这是一个相对较新的API,似乎IE尚未支持.

  • 请注意,一些广告拦截器(如uBlock Origin)阻止了Navigator.sendBeacon的某些跟踪预防感.因此,您的应用根本无法依赖它. (2认同)

Gyu*_*hoi 5

同步XMLHttpRequest已被弃用(同步和异步请求)。因此,jQuery.ajax()async: false选项也已被弃用。

beforeunload在或unload ( Ajax Synchronous Request Failing in Chrome )期间使用同步请求似乎是不可能的(或非常困难)。所以建议使用sendBeacon,我绝对同意!

简单地:

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);
});
Run Code Online (Sandbox Code Playgroud)