unload 事件可以用来可靠地触发 ajax 请求吗?

发布于 2024-09-16 06:12:50 字数 372 浏览 2 评论 0原文

我需要一种方法来监视用户编辑会话,我正在审查的解决方案之一将让我使用 unload 事件发送 ajax 请求,以通知服务器编辑会话结束。 (请参阅:监视用户会话以防止编辑冲突

我的(而不是限制)读取 unload 事件表明附加到该处理程序的代码必须快速运行,因此通常用于清除对象以防止内存泄漏。

我的问题是,这可以足够可靠地实现此目的吗?

附言。我知道 async: false 选项。

I need a method to monitor user edit sessions, and one of the solutions I'm reviewing will have me using an unload event to send an ajax request to inform the server of the end of the edit session. (See: Monitoring User Sessions to Prevent Editing Conflict)

My (rather limited) reading on the unload event indicates that the code attached to this handler has to run quickly, and as such, is usually used for clearing objects to prevent memory leaks.

My question is, can this work reliably enough for this purpose?

PS. I know about the async: false option.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

妳是的陽光 2024-09-23 06:12:50

如果您的服务器响应速度足够快,则此方法相当可靠。不过确实需要注意一些事情。如果您关闭浏览器并在卸载事件时发送 AJAX 请求,则在窗口对象被销毁之前,响应很可能无法及时从服务器返回。在这种情况下(至少对于 IE)会发生什么,它将孤立您的连接对象,并且在连接超时之前不会正确终止它。如果您的服务器没有打开连接保持活动状态,则在您关闭 2 个窗口(同时仍打开另一个窗口)后,您将耗尽与服务器的打开连接(对于 IE6-7,对于 IE8 - 6 个窗口)在连接超时之前,您将无法打开网站。

我之前遇到过这样的情况,我打开一个弹出窗口,在卸载时发送 AJAX 请求,它非常可靠,但它受到上述问题的困扰,我花了很长时间才跟踪它下来并了解发生了什么事。之后,我所做的就是确保打开的窗口将具有相同的代码来调用服务器,并且在每次卸载时检查打开器并在那里运行代码(如果存在)。

似乎如果您关闭最后一个浏览器窗口,IE 将正确破坏连接,但如果打开另一个窗口,则不会。

PS 只是为了评论上面的答案,AJAX 并不是真正的异步。至少它的 JS 实现不是。发送请求后,JS 代码仍然会等待服务器的响应。它不会阻止您的代码执行,但由于服务器可能需要一段时间才能响应(或者 Windows 需要足够长的时间来终止 IE 窗口对象),因此您可能会遇到上述问题。

This method is fairly reliable, if your server is fast enough to respond. Something to really watch out for though. If you close the browser and send AJAX request on unload event, there's a very good chance that the response isn't going to come back from the server in time before the window object is destroyed. What happens in this case (at least with IE) is that it will orphan your connection object and not terminate it correctly until the connection timeout is hit. If your server doesn't have connection keep-alive turned on, after you close 2 windows (while still having another window open), you will run out of open connections to the server (for IE6-7, for IE8 - 6 windows) and you will not be able to open your website until your connection timeout is hit.

I ran into a situation like that before were I was opening a popup window that was sending an AJAX request on unload, it was very reliable, but it was plagued by the issued described above, and it took really long time for me to track it down and understand what's going on. After that, what I did, is I made sure that opening window would have the same code to call server, and on every unload checked for the opener and ran the code there if it was present.

It seems that if you close the very last browser window, IE will destroy connection properly, but if one other window is open, it will not.

P.S. And just to comment on the answer above, AJAX is not really async. At least JS implementation of it isn't. After you send a request, you JS code is still going to be waiting for response from the server. It's not going to block your code execution, but since the server might take a while to response (or long enough for Windows to terminate IE window object) you might and probably will run into the problem described above.

生来就爱笑 2024-09-23 06:12:50

您是否尝试过使用

var i = new Image(1,1); 
i.src='http://...'

And just returns some empty image from server.我认为它应该是可靠的,脚本会阻塞。顺便说一句:很高兴添加时间戳以防止缓存。

Have you tried to use

var i = new Image(1,1); 
i.src='http://...'

And just returning some empty image from server. I think it should be reliable, script will block. BTW: nice to add timestamp to prevent caching.

我的黑色迷你裙 2024-09-23 06:12:50

我们有一个案例需要这样做。这是一个需要服务器上大量内存的报告页面,因此我们希望在他们离开页面后立即释放它。我们创建了一个框架集并在其中添加了卸载处理程序。最可靠的方法是将图像的 src 设置为释放脚本。我们实际上使用了 unload 和 onbeforeunload 来实现跨浏览器兼容性。它在网络套件夜间版中不起作用,但管理层对此表示同意。

然而,这不是我提出的解决方案。我会使用心跳方法,该方法涉及更多工作,但更稳健。

您的页面应该定期发送心跳请求。每个请求都会设置页面的最后一个心跳。然后,您需要一个在服务器上运行的线程,并在上次心跳发生太久之前清除内存。

这并不能解决页面长时间打开的问题。为此,您需要对用户活动进行一些监控,并在一段时间不活动后离开该页面(确保与用户确认)

We have a case where we needed that. It's a report page that needs serious memory on the server so we wanted to free it immediately as soon as they left the page. We created a frameset and added the unload handler there. The most reliable way was to set the src of an image to the freeing script. We actually used both the unload and onbeforeunload for cross browser compatibility. It didn't work in web kit nightlies but management was OK with that.

However, that was not my proposed solution. I would use a heartbeat approach which involves more work but is much more robust.

Your page should send out periodical heartbeat requests. Each request sets the last heartbeat from a page. You then need a thread that runs on the server and clears memory if the last heartbeat was too long ago.

This doesn't solve the problem of leaving the page up for a long time. For that you need some monitoring for user activity and leave that page after a period of inactivity (make sure you confirm with the user)

难忘№最初的完美 2024-09-23 06:12:50

您必须自己测试您的特定场景是否适合您在 unload 中的时间,但发出 AJAX 请求非常快,因为 AJAX 是异步的。您只需发送请求即可完成! (不过,也许您必须清除刚刚创建的请求对象。)

如果您想验证 AJAX 请求是否已发出,那么您必须更加担心/使用 async:false 选项(如此讨论所示)。但是,只需发送即可完成快速操作。

You'll have to do your own testing about whether or not your particular scenario works with the time you have in unload, but making the AJAX request is pretty fast, since AJAX is asynchronous. You just send the request and then you're done! (Maybe you'll have to clear the request object you just created, though.)

If you wanted to verify that the AJAX request made it, then you'd have to worry more/use the async:false option (like this discussion indicates). But, just sending is a quick boom-and-you're-done operation.

凉月流沐 2024-09-23 06:12:50

我遇到过这样的情况,我只需要通知服务器端有关卸载的信息,而不关心响应。

如果这是你的情况,你可以 ignore_user_abort 然后你就知道了它会“可靠地”发生

I had a case in which I only needed to notify server side about the unload and didn't care about the response.

If thats your case you can ignore_user_abort and then you know it'll happen "reliably"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文