Can beforeunload/unload be used to send XmlHttpRequests reliably

倾然丶 夕夏残阳落幕 提交于 2019-11-27 20:32:09

问题


recently, I had the urgent requirement to give my server a notice, that a specific page of my webapp is about to get closed. "Easy peasy" I thought, beforeunload is available for quite a while. The HTML5 "thing" even refreshed the spec (that was what I thought...) about it, in the way that we had the option to return a string value from a beforeunload event handler and stuff, which gives an user the option to intercept.

See the MDN page about onbeforeunload

However, as it turned out, there isn't any "official" specification available, which describes the behavior for beforeunload up to this date. The only official document I found, was on WHATWG, which is just a proposal for W3C of course.

See WHATWG

So far so good. We are able to create a synchronized XHR request within a beforeunload event handler. "Most" browsers, give that request a timeframe of about 1-2 seconds to complete, after that it is getting killed. Standard asynchronous request are killed immediately. Having that said, I cannot even tell from "where" I know this, it seems like gossip and word of mouth looking at it now. Even tho, it works in Firefox+Chrome, we cannot rely on that, can we ?

Is there any ongoing discussion/proposal on WHATWG about beforeunload ?
Any other official resources about the event I might have not found ?

And far most important to me here, how reliably can we send data via sync-XHR there ?


回答1:


Take a look at navigator.sendBeacon(), which allows you to reliably send data to a server even when the page is unloading. It's currently in a draft specification and supported by Firefox 31, Chrome 39 (behind a flag from 37), behind a flag in Opera 24.

You could "sort of" polyfill it using something like the following:

navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
    var xhr = new XMLHttpRequest();

    // Need to send synchronously to have the best chance of data getting
    // through to the server
    xhr.open('POST', url, false);
    xhr.send(data);
};

Further reading:

  • HTML5 Rocks article



回答2:


The thing to keep in mind is that beforeunload started as an extension by Internet Explorer. Automatically, that makes it a second-class citizen on the web. There is no specification, and browser implementation varies. For example, Firefox only partially implements it by not displaying the string, only a generic message.

Additionally, even when fully implemented, it does not protect against all possible unload scenarios, eg, the user has terminated the processor, the browser has crashed, or the computer has been turned off. Even ignoring these extreme scenarios, I suspect that it might be possible to configure your browser to ignore such requests.

My feeling is that you shouldn't rely on this message to save you. If this web app is internal, I would suggest training them to use the Save or Close or whatever buttons instead of just closing the tab. If it's external, maybe look into automatic saving as the user does their thing?




回答3:


Sync XHR is a top-source of browser hangs, accounting for nearly 10% of hangs: http://blogs.msdn.com/b/ieinternals/archive/2011/08/03/do-not-use-xmlhttprequest-in-synchronous-mode-unless-you-like-to-hang.aspx

In IE, even sync XHR can be "interrupted" if the request requires Windows authentication roundtrips, or if there's a POST body to be sent. You may find that only the headers of the first unauthenticated request are sent.



来源:https://stackoverflow.com/questions/15479103/can-beforeunload-unload-be-used-to-send-xmlhttprequests-reliably

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