【问题标题】:Send an Ajax Call on beforeunload/unload在卸载/卸载之前发送 Ajax 调用
【发布时间】:2017-09-01 01:57:34
【问题描述】:

场景:我正在创建一个活动注册模块,用户可以在其中从日历中选择一个日期进行预订,填写一些输入字段并支付预订日期。 其中一项要求是,每个日期只能有一个预订。 这会出现两个人想在同一时间预订同一日期的情况。因此,我们需要向后来预订日期的用户显示一条消息,该特定日期的预订已经在进行中。请稍后再回来查看。

为此,每当用户选择日期时,我都会在我的数据库中创建一个临时条目。针对该条目,我可以将消息显示给稍后到达的其他用户。

从逻辑上讲,如果第一个用户出现以下情况,则必须删除该条目:

  1. 选择其他日期。
  2. 关闭浏览器或离开页面

以便第二个想要在同一日期预订的用户可以使用它。

问题:一旦用户更改了他选择的日期,我就可以删除该条目。我无法实现第二个。我编写了一个函数,它将删除该行并在 onbeforeunload jQuery 事件上调用该函数。显然,该函数不适用于 jQuery。

window.onbeforeunload = function(){
  deleteTempEntry(); //This sends an ajax call to delete the entry. Not working.

  alert("The second alert"); // even this alert doesn't work.

  // I actually intend to use confirm box to make sure to not to delete the entry if the user does not leave the page.
  confirm("Your current progress will be removed. Are you sure?"); 

  //Calling this return function shows the warning message but none of the other code works.
  //return 'Are you sure you want to leave?';
};

我尝试过,绑定/开启/纯 JS,但这些似乎都不起作用。

正如here 解释的那样,由于安全原因,我对 onbeforeunload/unload 事件无能为力。 有什么解决方法吗?

谢谢。

【问题讨论】:

  • 打开一个新窗口怎么样?然后在那里显示您的消息,弹出窗口上的卸载应该触发deleteTempEntry()
  • 因此,当用户关闭选项卡/浏览器时,您在前端无能为力。所以你必须在后端维护一个超时功能,以便它删除不完整的注册。

标签: javascript php jquery ajax date


【解决方案1】:

您可以让客户端每 30 秒左右向服务器发送一次“心跳”,并使用上次发送的心跳的时间戳以及对预订日期的引用来更新数据库中的记录。然后运行一个每分钟左右运行一次的 cronjob,它会检查所有这些记录,如果其中一个已经结束,比如说超过 120 秒,则删除该记录。

【讨论】:

  • 有道理。但我们实际上给了用户 20 分钟的时间来完成表格并进行交易。之后,会话将过期。结合该要求,不幸的是,应用您建议的方法会导致问题。
  • 您可以延长超时时间。这可能是唯一可靠的解决方案,您需要它,因为它是您系统的重要组成部分。
【解决方案2】:

尝试console.log 并在您的 onbeforeunload 方法中返回。也许用户在您的 ajax 通过之前离开了页面。

见: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload

自 2011 年 5 月 25 日起,HTML5 规范规定调用

  • window.alert()
  • window.confirm()
  • window.prompt()

在此事件期间可能会忽略命令。

【讨论】:

  • 我明白这一点。这就是为什么我计划使用确认方法以确保 ajax 请求通过。但是confirm(),alertI(),它们不起作用。
  • @Symbolwdd - 我不确定这一点,但尝试在 beforeunload 函数中发送一个 ajax 并从 ajax 的响应中返回 null。再次,不确定,只是想给出一个想法。因为此方法返回值时会触发 beforeunload 提示。
  • 感谢您提供的文档。看起来 onbeforeunload 已经不在桌面上了。在这种情况下,我将不得不转向 cron 工作。
【解决方案3】:

您可以像这样使用 async: false 发布数据:

$(window).unload(function () {
            $.ajax({
                type: 'POST',
                async: false,
                url: 'your url',
                data: {  }
            });
        });

【讨论】:

  • 同步请求会导致浏览器无响应,直到请求完成。
  • 这是一个同步调用,因此它会阻止进一步的代码执行,直到请求完成。
  • 你是对的,但你正在离开页面。不是吗?没关系。
  • @MajidParvin,我无法使用 onbeforeunload 技术解决问题。我已经进一步研究,你可以用 unbeforeunload 做的功能非常有限。事实上,它只是一个可以返回的字符串,在最新版本的浏览器中,他们甚至会倾向于忽略它。所以,我宁愿转向 cron 工作方法。感谢您的宝贵时间。
  • @VladimirDemirev 似乎是正确的, async: false 在较新版本的浏览器中不起作用。见usefulangle.com/post/62/…
【解决方案4】:

我需要这样的东西。但不幸的是,在 onBeforenUnload 中调用后端并不可靠。大多数 AJAX 调用不会到达后端(有些可能); 唯一保证调用的是 navigator.sendBeacon(url, data)。即使浏览器关闭,它也会发送 POST 请求。

【讨论】:

猜你喜欢
  • 2013-02-02
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 2014-02-09
  • 1970-01-01
相关资源
最近更新 更多