beforeunload/unload能够可靠地用于发送XmlHttpRequests吗?

21

最近,我急需通知我的服务器,一个特定的网页即将关闭。我想 "Easy peasy",beforeunload 已经存在了很长时间。HTML5 甚至刷新了 spec(我当时是这么认为的...),我们可以从 beforeunload 事件处理程序中 return 一个 string value 等,这使得用户有了拦截的选项。

请查看MDN关于onunload的页面

然而,事实证明,到目前为止,并没有任何 "official" 规范来描述 beforeunload 的行为。我找到的唯一官方文档在 WHATWG 上,当然只是 W3C 的一个提案。

请看 WHATWG

到目前为止还好。我们能够在 beforeunload 事件处理程序中创建一个 synchronized XHR request。 "大多数" 浏览器会给请求约1-2秒的时间来完成,之后它就会被杀死。标准的 asynchronous request 则立即被杀死。虽然在 Firefox+Chrome 中它可以工作,但我们不能依赖它,对吧?

关于 beforeunload 有什么正在进行的讨论/提案吗?
我可能没有找到的其他官方资源?

对我来说,最重要的是我们能否通过同步XHR可靠地发送数据。


我正在使用YUI3事件处理来使用此事件(这对于这个问题并不重要),并且使用XHR进行“fire and forget”异步调用到服务器(为大型内部会计应用程序记录统计信息,以查看用户实际使用应用程序的哪些页面以及使用时间有多长 - 只有当他们离开页面后,我才能记录停留在页面上的持续时间)。我在FF(最新版本)和IE 7和8上进行了测试 - 运行良好。 - Mörre
3个回答

20
请查看navigator.sendBeacon(),它允许您在页面卸载时可靠地向服务器发送数据。该功能目前处于草案规范阶段,并且受到Firefox 31、Chrome 39(从37开始使用标志)以及Opera 24中的标志支持。
您可以“有点像”使用以下内容来模拟它:
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);
};

更多阅读:


好的答案。正如我所说,我甚至不知道它来自哪里,我只知道它有效。在特定时间段后,浏览器将取消请求。这有点像忽略模态窗口调用的情况。我不知道Hixie说过那话,但听起来真的很糟糕。当然,即使事件得到了良好的规范和实现,也不能涵盖所有“流星撞地球”崩溃情况,但对于大多数自动保存通知情况来说,它可能已经足够好了。这是为了标签/窗口关闭、重定向、浏览器关闭。 - jAndy
2
“没有什么比未指定的功能更糟糕的了。”-(jAndy,2013) - jAndy
1
我想知道为什么这样的功能可以实现,因为XMLHttpRequest并不是唯一的异步方法?为什么他们不引入一个可靠地处理页面卸载时异步操作的事件呢?为什么??? - Lewis
1
注意:从Chrome 59开始,使用json(或任何非简单CORS)内容类型的navigator.sendBeacon将引发异常。 显然是暂时的,直到解决安全问题。 请参见:http://crbug.com/490015 - steevee
1
同步 Ajax 自 Chrome 73 起不再受支持。 相关 Chrome 功能:https://www.chromestatus.com/feature/4664843055398912 - cor3000
显示剩余2条评论

4
需要翻译的内容如下:

请记住,beforeunload最初是由Internet Explorer作为扩展功能启动的。这使它在Web上成为二等公民。没有明确的规范,并且浏览器实现也有所不同。例如,Firefox仅部分实现它,不显示字符串,而只显示通用消息。

此外,即使完全实现,它也不能保护所有可能的卸载场景,例如,用户已终止处理器、浏览器崩溃或计算机已关闭。即使忽略这些极端情况,我认为可能可以配置浏览器忽略此类请求。

我的感觉是您不应该依赖此消息来保存数据。如果这个Web应用程序是内部的,我建议培训他们使用SaveClose或其他按钮,而不仅仅是关闭选项卡。如果是外部应用程序,也许可以考虑在用户操作时自动保存?


它是在HTML中指定的,自2000年代后期以来一直如此。 - gsnedders

2

我认为你误解了重点。正如我所提到的,同步xhr请求是在beforeunload处理程序中向服务器发送数据的唯一方法。浏览器将允许这些类型的请求,但它们会在短时间内中止它们(这是一件好事)。实际上有趣的问题是,为什么它能够这样工作,谁定义了这种行为以及它是否可靠。 - jAndy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接