小编典典

Javascript:等到ajax请求完成以关闭页面时

ajax

我希望浏览器将页面保持打开状态,直到发送ajax请求为止。这就是我想像的样子

var requestsPending = 0;

window.onbeforeunload = function() {
    showPleaseWaitMessage();
    while(requestsPending > 0);
}

// called before making ajax request, atomic somehow
function ajaxStarted() {
    requestsPending++;
}
// called when ajax finishes, also atomic
function ajaxFinished() {
    requestsPending--;
}

不幸的是,JS不执行多线程。据我了解,回调(ajaxFinished)将永远不会执行,因为浏览器将尝试等待while循环完成以执行它,因此,它将永远循环。

什么是正确的方法?也许有一种方法可以迫使JS评估待办事项列表中的下一件事,然后返回while循环?还是一些与ajax调用“联接”的语法?我正在为我的ajax使用DWR。

谢谢-Max


阅读 516

收藏
2020-07-26

共1个答案

小编典典

编辑 根据您在下面的评论,修改后的答案:

如果要阻止直到 先前启动的 请求完成,可以这样:

window.onbeforeunload = function(event) {
    var s;
    event = event || window.event;
    if (requestsPending > 0) {
        s = "Your most recent changes are still being saved. " +
            "If you close the window now, they may not be saved.";
        event.returnValue = s;
        return s;
    }
}

然后,浏览器将提示用户询问他们是要离开页面还是留在页面上,从而将其置于控制之下。如果他们停留在页面上并且在提示出现时请求已完成,则下次他们关闭页面时,它将使他们无需询问即可关闭页面。

请注意,在现代浏览器中,您的消息将不会显示。而是,浏览器将使用通用消息。因此,在现代浏览器上,返回任何非空字符串就足够了。不过,如果您的用户使用的旧浏览器仍会显示该字符串,则您可能需要返回一个有用的字符串(例如上述字符串)。

有关询问用户是否在此处此处取消关闭事件的更多信息


旧答案

理想情况下,如果可能,您要 避免 这样做。:-)

如果你无法避免它,它可能使一个Ajax请求 同步
,以阻塞的onbeforeunload过程,直到它完成。我不知道DWR,但我希望它有一个标志来控制请求是否同步。在原始XmlHTTPRequest
API中,这是第三个参数open

req.open('GET', 'http://www.mozilla.org/', false);
                                            ^ false = synchronous

大多数将具有等效的。例如,在Prototype中,它asynchronous: false是选项中的标志。

但是同样,如果您可以避免在页面卸载过程中触发Ajax请求,那么我会这样做。建立,传输和完成请求时,会有 明显的
延迟。让服务器使用超时来关闭它要好得多,这要好得多。(这可能是一个相当短的超时;您可以通过在打开页面时定期在页面中使用 异步
Ajax请求来使会话保持活动状态-例如,一分钟一分钟,两分钟后超时。)

2020-07-26