Почему мой XMLHttpRequest отменяет мою фоновую задачу перед перезагрузкой страницы

Я пытаюсь отправить XMLHttpRequest на бэкэнд, если пользователь решает перезагрузить веб-страницу во время выполнения задачи на бэкэнде. Это должно работать следующим образом:

  1. Пользователь запускает задание (перевод).
  2. Если пользователь решает перезагрузить страницу или перейти в другое место, он должен получить предупреждение о том, что задание будет остановлено, если он перейдет в другое место. Если пользователь все же решит уйти, запрос будет отправлен в представление 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

Вернуться на верх