Почему мой XMLHttpRequest отменяет мою фоновую задачу перед перезагрузкой страницы
Я пытаюсь отправить XMLHttpRequest на бэкэнд, если пользователь решает перезагрузить веб-страницу во время выполнения задачи на бэкэнде. Это должно работать следующим образом:
- Пользователь запускает задание (перевод).
- Если пользователь решает перезагрузить страницу или перейти в другое место, он должен получить предупреждение о том, что задание будет остановлено, если он перейдет в другое место. Если пользователь все же решит уйти, запрос будет отправлен в представление
stop_task
на бэкенде.
Однако в настоящее время, если пользователь начинает перемещаться или перезагружаться, задача завершается, как только появляется предупреждение, а не после того, как пользователь подтверждает, что он все еще хочет перезагрузиться/переместиться.
Вот мой код JS:
wwindow.addEventListener('beforeunload', function (e) {
if (isTranslating) {
stopTranslation();
e.preventDefault();
e.returnValue = '';
return 'Translation in progress. Are you sure you want to leave?';
}
});
function stopTranslaion() {
if (isTranslating && currentTaskId) {
// Cancel the polling
console.log(currentTaskId)
clearInterval(pollInterval);
// Send a request to the server to stop the task
const xhr = new XMLHttpRequest();
xhr.onload = function() {
if (xhr.status == 200) {
const response = JSON.parse(xhr.responseText);
if (response.status === 'stopped') {
console.log('Translation stopped');
isTranslating = false;
currentTaskId = null;
// Update UI to reflect stopped state
showTranslationStopped();
}
} else {
console.error('Failed to stop translation');
}
};
xhr.onerror = function() {
console.error('Connection error while trying to stop translation');
};
xhr.open('POST', `/translate/stop_task/${currentTaskId}/`, true);
xhr.setRequestHeader('X-CSRFToken', getCsrfToken());
xhr.send();
}
}
function showTranslationStopped() {
// Update UI to show that translation has been stopped
translatingFileField.style.display = 'none';
const stoppedMessage = document.createElement('div');
stoppedMessage.textContent = 'Translation has been stopped.';
form.appendChild(stoppedMessage);
}
views.py:
@csrf_protect
def stop_task(request, task_id):
if request.method == 'POST':
try:
# Revoke the Celery task
app.control.revoke(task_id, terminate=True)
return JsonResponse({'status': 'stopped'})
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)
Я бы предпочел, чтобы он функционировал так, как описано в шагах 1 и 2. Мои задачи решаются с помощью Celery с redis