在注销时自动保存“卸载”事件和ajax调用:操作顺序导致问题

时间:2011-06-13 17:07:45

标签: jquery ajax events onbeforeunload

我在在线编辑器上使用自动保存功能。

当用户离开页面时(使用unloadbeforeunload事件检测到),我发送了一个AJAX请求(async = false)来保存数据。

我在Firefox中遇到了一个问题,有时候会在Chrome中出现问题,因为发生了一系列事件:

  • 事件被解雇
  • 请求发送
  • 页面更改且用户已断开连接
  • 服务器分析请求=>问题!
  • 浏览器收到的请求回复

当然,由于用户已断开连接,因此无法处理“保存”请求。

在页面实际发生变化之前,有没有办法与所有浏览器兼容,等待AJAX​​调用的响应?

5 个答案:

答案 0 :(得分:11)

ori的回答是正确和完整的。

但根据您的情况判断,您可以使用解决方法。

您可能感兴趣的有两个JavaScript功能: localStorage和sessionStorage(它是相同的,除了第二个在浏览器关闭时被清除,所以你可能会选择第一个)

我们的想法是将数据保存到localStorage,其中包含一些元数据,说明是否保存了更改。如果用户离开页面但转到服务中的另一个页面,甚至稍后返回 - 您可以再次发送数据,其中包含由于页面卸载而未保存的一些信息。

概念证明代码:

$(window).bind('unload', function() {
    localStorage.setItem('unsavedData',data);
    localStorage.setItem('unsaved',true);
});

$(document).ready(function(){
    if(localStorage.getItem('unsaved')){
       //ajax send 
       localStorage.setItem('unsaved',false);
    }
});

[编辑]

我已经成功地将JSONP与unload一起使用,并且它似乎在大多数时间都有效,但我还没有在加载和慢速网络上测试它。

答案 1 :(得分:6)

没有。您只能向用户显示确认对话框:

$(window).bind('beforeunload', function() {
    // AJAX

    return 'STRING';
});

STRING将显示在对话框中,然后您可能有时间让用户回复之前回复。

但这是阻止页面卸载的唯一方法,因此不会收到ajax响应。

答案 2 :(得分:0)

页面顶部的固定透明div如何通过悬停事件触发保存?只是从创造性的角度思考...保留你现在的保存,但作为一个故障保护,我在想如果普通用户要离开,首先他们会将鼠标移动到地址栏,后退按钮或关闭按钮。如果您捕获DOM窗口的顶部,可能会在最后一分钟的保存中获得更多成功吗?

此外,您可以在setTimeout()上推送更改,但听起来您的目标比我的解决方案更有限。

答案 3 :(得分:0)

将async变为false会更容易。

否则您可以使用async:true调用服务器,当它成功返回或出错时,您可以为注销/重定向/错误消息引发自定义事件。

悬停透明div可用于让用户等待服务器响应。

答案 4 :(得分:0)

我正在使用onbeforeunload来获得类似的东西,但是我的数据有效负载非常小(一个guid),而且我不需要任何返回值,所以它很火,忘了。它可以在95%的时间内工作,但是不同的浏览器以不同的方式实现onbeforeunload,onunload等。

你可以使用未保存的数据弹出另一个窗口,然后在你的请求被触发后关闭该窗口,但这里的关键元素是'pop' - 可能会被阻止。可以使用上面的本地存储答案。

当然,第一个解决方案 - 询问用户,然后让他们保存可能是最好的。也许他们正在关闭以防止保存自上次保存以来的任何更改?