Я работаю с веб-приложением, которое блокирует ресурсы на сервере. Чтобы разблокировать их, необходимо удалить ресурс на сервере с помощью 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 до тех пор?
[ОБНОВЛЕНИЕ] Решение было следующим: синхронно используйте XMLHttpRequest. Это шумно устарело, но (на момент написания) все еще работает, по крайней мере, в Chrome.
var request = new XMLHttpRequest();
request.open('DELETE', url, false);
request.setRequestHeader('X-XSRF-TOKEN', myXSRFToken);
request.send();