JavaScript: не выгружать документ, пока не завершится HttpRequest - PullRequest
3 голосов
/ 25 февраля 2011

Мне нужно убедиться, что когда кто-то перезагрузит или закроет мою страницу, его прогресс будет сохранен.Чтобы сохранить прогресс, я делаю POST через XMLHttpRequest(), отправляя данные на сервер.Я запускаю эту функцию saveData() внутри события window.onbeforeunload.

Проблема в том, что saveData() выполняет некоторые вычисления, а затем вызывает sendData(content), чтобы, наконец, на самом деле отправить данные.И если данные, которые я обрабатываю и отправляю, имеют большой размер (> 100 КБ), кажется, что окно закрывается до того, как все данные поступят на сервер.(Я отправляю изображение, и иногда я получаю только половину его на другой стороне)

HTTP-запрос является синхронным, xhr.open("POST", url, false), но это не похоже на его сокращение.

Итак, мой вопрос, как я могу предотвратить завершение функции onbeforeunload, ДО 1014 *?Как заставить его ждать этого события?

О, и setTimeout() не будет работать.Окно закроется до наступления времени.

Это не сработает:

if (!jQuery) {
    setTimeout(attachCode, 100);
    return;
} else {
    // continue and close
}

Спасибо за понимание!

PS: это не должно быть "плохой практикой", поскольку это займет всего несколькосекунд, и я не хочу, чтобы пользователь должен был сохранять вручную.Кроме того, сохранение, пока он работает (как прежде, чем он закроет окно), замедлит работу приложения, поэтому я не могу этого сделать.

[EDIT] В качестве временной меры я прибегнул к использованию этот трюк для автоматического сохранения данных, если пользователь решает остаться на странице.Тем не менее, мне бы очень хотелось, чтобы не было необходимости использовать какие-либо сообщения с предупреждениями.(

Ответы [ 2 ]

1 голос
/ 25 февраля 2011

На самом деле вы можете замедлить работу браузера перед выгрузкой.Проблема заключается в том, как JS обрабатывает запросы Ajax.

Некоторое время назад мне пришлось быстро и грязно взломать почти одно и то же - записать некоторые вещи перед навигацией.Единственный способ сделать это - дождаться возвращаемого значения запроса XHR.

Несмотря на то, что это синхронно, выполнение кода разветвляется в фоновом режиме и фактически не блокирует браузер.Вы должны получить возвращаемое значение, чтобы иметь возможность остановить скрипт для загрузки данных.

Имейте в виду, что я использовал jQuery для этого, но это относится к нативному JS (я думаю ..:))

/* some code above */
var request = {
    async:false,
    cache: false,
    url: this.serviceURL,
    type: 'POST',
    data: {...},
    success: function(data) {}
};
try {
    var asd = $j.ajax(request); // do the request and wait
}
catch (e) {}
/* some code below */

Надеюсь, это поможет.

1 голос
/ 25 февраля 2011

Запрещение браузеру вести себя нормально, как правило, плохая идея.А с onbeforeunload вы не можете приостановить выгрузку, вы можете только дать пользователю знать, что он / она покидает страницу, а затем позволить ему решить, покинуть страницу или нет - и, таким образом, данные не сохранятся.

Так что в вашем случае я бы предложил черновик автосохранения, как вы видите в документах Google + предупреждение, когда пользователь покидает страницу с несохраненными данными.

...