JavaScript:在HttpRequest完成之前不要卸载文档

时间:2011-02-25 10:14:03

标签: javascript event-handling xmlhttprequest onbeforeunload

我需要确保当有人重新加载或关闭我的页面时,他们的进度会被保存。为了保存进度,我通过POST进行XMLHttpRequest(),将数据发送到服务器。 我在saveData()事件中触发了此window.onbeforeunload函数。

问题是,saveData()做了一些计算,然后调用sendData(content)来最终实际发布数据。 如果我正在处理和发送的数据很大(> 100kB),则在所有数据通过服务器之前窗口似乎关闭。 (我正在发送一张图片,有时我只会在另一边发一半)

http请求是同步的,xhr.open("POST", url, false),但这似乎并没有削减它。

所以我的问题是,如何让onbeforeunload函数终止,UNTIL xhr.readyState == 4?如何让它等待那个事件?

哦,setTimeout()不起作用。窗口将在“时间”到来之前关闭。

这不起作用:

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

感谢您的任何见解!

PS:这不应该是“糟糕的做法”,因为它只需要几秒钟,我不希望用户必须手动保存。此外,在他工作时保存(例如,在他关闭窗口之前)会减慢应用程序,所以我不能这样做。

[编辑]作为临时措施,如果用户决定留在页面上,我会使用this trick自动保存数据。但是,我真的不想使用任何警报消息。 :(

2 个答案:

答案 0 :(得分:1)

禁止浏览器执行此操作通常是一个坏主意。使用onbeforeunload您无法暂停卸载,您只能让用户知道他/她离开页面然后让他们决定是否离开页面 - 因此数据未保存

所以我的情况,我会建议自动保存草案,就像你在Google文档中看到的那样+当用户离开页面时出现未保存数据的警告。

答案 1 :(得分:1)

实际上,您可以在卸载前减慢浏览器的速度。问题在于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 */

我希望这会有所帮助。