Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript/angular:从onunload执行异步http_Javascript_Angularjs_Onunload - Fatal编程技术网

Javascript/angular:从onunload执行异步http

Javascript/angular:从onunload执行异步http,javascript,angularjs,onunload,Javascript,Angularjs,Onunload,我正在使用一个锁定服务器上资源的web应用程序。要解锁它们,它必须使用HTTP delete删除服务器上的资源。我知道这是不可靠的,有一个定期清理运行,以及解锁他们,但目标是解锁资源尽快 我不能改变锁定架构(它不是我的系统),我只需要在解锁时尽最大努力 我需要解锁的一点是当选项卡或浏览器关闭时。首先,我正在处理onbeforeunload,如果文档是脏的,则提示用户确认要关闭: $window.onbeforeunload = function() { if (documentIsDir

我正在使用一个锁定服务器上资源的web应用程序。要解锁它们,它必须使用HTTP delete删除服务器上的资源。我知道这是不可靠的,有一个定期清理运行,以及解锁他们,但目标是解锁资源尽快

我不能改变锁定架构(它不是我的系统),我只需要在解锁时尽最大努力

我需要解锁的一点是当选项卡或浏览器关闭时。首先,我正在处理onbeforeunload,如果文档是脏的,则提示用户确认要关闭:

$window.onbeforeunload = function() {
    if (documentIsDirty) {
        return "Some prompt text";
    }
};
我无法在onbeforeunload中解锁,因为用户可能会选择取消关闭。但是onbeforeunload和onunload之间没有任何事件(如果我错了,请纠正我)

如果我尝试从onunload中进行调用,那么一旦onunload函数返回,选项卡/会话就会被销毁。问题是,那是在http请求完成之前,结果发现资源实际上没有解锁

$window.onunload = function() {
    $http.delete('/a/lock/url');

    // I've tried forcing a digest cycle to try and flush the request
    // through, but it never gets sent either way
    $rootScope.$digest();
};
现在,我知道在Javascript中实际阻塞是令人讨厌的,但似乎一旦onload返回,她就写了这么多

在http请求实际完成之前,是否有任何方法阻止onunload,并防止onunload在此之前返回

[更新] 解决方案如下-同步使用XMLHttpRequest。虽然有人极力反对它,但至少在Chrome中(在撰写本文时)它仍然可以工作

var request = new XMLHttpRequest();
request.open('DELETE', url, false);
request.setRequestHeader('X-XSRF-TOKEN', myXSRFToken);
request.send();

$http将始终异步执行请求,因为它在内部只是使用
XMLHttpRequest
并始终将
true
作为第三个参数传递给请求的
open
函数。从MDN文档中获取:

可选的布尔参数,默认为true,指示是否异步执行操作。如果此值为false,则在收到响应之前,send()方法不会返回


如果要执行同步请求,可以直接使用
XMLHttpRequest
,并将
false
作为第三个参数传递给
open
。因为这是网站关闭的时候,所以实际上没有必要使用Angular的$http。

最近,我们在进行此类活动时遇到了同样的问题,并通过使用
navigator.sendBeacon()
解决了这个问题。
navigator.sendBeacon()
方法通过http向web服务器异步发送少量数据。对于最新的浏览器,您可以这样做

window.addEventListener('beforeunload', function (event) {
    data = new FormData();
    // for CSRF Token
    token = $('meta[name="csrf-token"]').attr('content');
    data.append("key", value);
    data.append("authenticity_token", token);
  
    navigator.sendBeacon("URL", data);
    
    // Cancel the event as stated by the standard.
    event.preventDefault();
    // Chrome requires returnValue to be set.
    event.returnValue = 'Are you sure you want to leave this page without saving?';
  });

有关签出和

的更多详细信息,据我所知,您希望在关闭浏览器之前执行并完成一些操作。您是否尝试过使用模式确认或Javascript确认,并在HTTP DELETE返回后自己执行关闭操作?嗯……我已经看到了两种方法来解决这个问题,它们不会得到“永不阻塞”的手腕拍击,比如async:false thing:navigator.sendBeacon“此方法解决了分析和诊断代码的需求,这些代码通常在卸载文档之前尝试将数据发送到web服务器。“另一种方法是使用WebSocket。服务器可以判断套接字何时断开,因此您可以在服务器端解锁。实际上,我使用WebSocket的方法有几种不同。同一页面中也可能存在重复:注意:从Gecko 30.0(Firefox 30.0/Thunderbird 30.0/SeaMonkey 2.27)开始),由于对用户体验的负面影响,主线程上的同步请求已被弃用。从长远来看,使用弃用的功能可能不是一个好主意…宾果,是的,这仍然有效。Mike说的没错,它被大量弃用,但这是我真正需要这样做的少数情况之一。我建议虽然它不起作用,但我只需要传递我的X-XSRF-TOKEN,然后一切都很好(除了大喊大叫的反对警告)。