Autosave with “unload” event and ajax call on logout : order of actions is causing an issue

心不动则不痛 提交于 2019-12-04 20:13:47

问题


I'm using a AutoSave feature on an online editor.

When an user leaves the page (detected with unload or beforeunload event), I'm sending a AJAX request (async = false) to save the data.

I have a problem in Firefox et sometimes in Chrome because that serie of events is happening :

  • event fired
  • request send
  • the page change and the user is disconnected
  • request analysed by the server => problem !
  • request response received by browser

Of course since the user has been disconnected the "save" request can't be handled.

Is there a way, compatible with all browsers, to wait for the response of the AJAX call, before the page actually changes ?


回答1:


ori's answer is correct and complete.

But judging from your case you could use a workaround.

There are two JavaScript features you might be interested in: localStorage and sessionStorage (it's the same except the second one is cleared on browser close, so you probabli will choose the first)

The idea is to save data to localStorage with some metadata stating if changes were saved. If the user leaves the page but goes to another page in your service, or even returns later - you can send the data again with some information that it was not saved due to page unload.

Proof of concept code:

$(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);
    }
});

[edit]

I have been successfully using JSONP with unload and it seemed to work most of the times, but I haven't tested it under load and on slow network.




回答2:


No. You can only display a confirm dialog to the user:

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

    return 'STRING';
});

The STRING will be displayed in the dialog, and then you might have time for the reponse to come back before user reacts.

But that's the only way you can block a page from unloading, hence the ajax response will not be received.




回答3:


What about a fixed transparent div across the top of your page with a hover event to fire the save? Just thinking form a creative point of view... Keep the save you have now, but as a failsafe, I'm thinking if the average user is going to navigate away, first they will move the mouse to the address bar, back button, or close button. If you capture the top of the DOM Window, maybe get a few more successful last-minute saves?

Also, you could push the changes on a setTimeout() but it sounds like you're going for something more finite than both of my solutions.




回答4:


Turning async to false would be easier thing to do.

Otherwise you could call server with async:true and when it returns either successfully or with error you can raise a custom event for logout/redirect/error message.

A hovering transparent div can be used to keep user waiting til the server responds.




回答5:


I am using onbeforeunload for something similar, but my data payload is quite small (a guid), and I don't need any return value, so it's fire and forget. It works around 95% of the time, but different browsers implement onbeforeunload, onunload, etc differently.

You could pop another window with the unsaved data, then close that window once your request has fired, but the key element here is 'pop' - chances are, that'll be blocked. T local storage answer above could be used by this.

Of course, the first solution - ask user, then let them save is probably the best. Perhaps they're closing to prevent saving any changes since the last save?



来源:https://stackoverflow.com/questions/6333721/autosave-with-unload-event-and-ajax-call-on-logout-order-of-actions-is-causi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!