我正在使用一个锁定服务器资源的Web应用程序。要解锁它们,它必须使用HTTP DELETE删除服务器上的资源。我知道这不可靠,并且定期清理也可以解锁它们,但目标是尽快解锁资源。
我无法改变锁定架构(它不是我的系统),我只需要在解锁时做出最好的准备。
我需要解锁的一点是选项卡或浏览器关闭时。首先,我处理onbeforeunload,如果文档是脏的,则提示用户确认他们要关闭:
$window.onbeforeunload = function() {
if (documentIsDirty) {
return "Some prompt text";
}
};
我无法在onbeforeunload中解锁,因为用户可能会选择取消关闭。但是在onbeforeunload和onunload之间没有事件(如果我错了,请纠正我)。
如果我尝试在onunload中进行调用,那么一旦onunload函数返回,tab / session就会被破坏。麻烦的是,在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在此之前返回?
[UPDATE] 解决方案如下 - 同步使用XMLHttpRequest。它被大声贬低,但(在撰写本文时)至少仍然在Chrome中使用。
var request = new XMLHttpRequest();
request.open('DELETE', url, false);
request.setRequestHeader('X-XSRF-TOKEN', myXSRFToken);
request.send();
答案 0 :(得分:1)
$ http将始终异步执行请求,因为在内部它只使用XMLHttpRequest
并始终将true
作为第三个参数传递给请求的open
函数。来自XMLHttpRequest's open function的MDN文档:
可选的布尔参数,默认为true,指示是否异步执行操作。如果此值为false,则send()方法在收到响应之前不会返回。
如果您想要执行同步请求,可以直接使用XMLHttpRequest
并将false
作为第三个参数传递给open
。由于这是在网站关闭时,无论如何都不必使用Angular的$ http。
答案 1 :(得分:0)
最近,在进行此类活动时遇到了相同的问题,并使用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?';
});
有关更多详细信息,请检出Navigator.sendBeacon()和Window: beforeunload event