简体   繁体   English

如何在AngularJS中发送HTTP请求onbeforeunload?

[英]How to send an HTTP request onbeforeunload in AngularJS?

I have a simple angular app that has two views that are loaded using ngRoute. 我有一个简单的角度应用程序,有两个使用ngRoute加载的视图。 I need to do some clean up on the server when the user navigates between views and when the user leaves the page (refreshes window, closes tab, or closes browser). 当用户在视图之间导航以及用户离开页面时(刷新窗口,关闭选项卡或关闭浏览器),我需要在服务器上进行一些清理。

My first stop was here: Showing alert in angularjs when user leaves a page . 我的第一站就在这里: 当用户离开页面时在angularjs中显示警报 It solved the first case where the user navigates between views. 它解决了用户在视图之间导航的第一种情况。 I've handled the clean up like this: 我已经像这样处理了清理工作:

$scope.$on('$locationChangeStart', function (event) {
    var answer = confirm("Are you sure you want to leave this page?")
    if (answer) {
        api.unlock($scope.id); //api is a service that I wrote. It uses angular $http service to handle communications and works in all other cases.
    } else {
        event.preventDefault();
    }
});

However, I haven't been able to handle the case where the user leaves the page. 但是,我无法处理用户离开页面的情况。 Following the above answer and this Google Groups post: https://groups.google.com/forum/#!topic/angular/-PfujIEdeCY I tried this: 按照上述答案和此Google网上论坛帖子: https//groups.google.com/forum/#!topic / angular / -PfujIEdeCY我试过这个:

window.onbeforeunload = function (event) {
    api.unlock($scope.id); //I don't necessarily need a confirmation dialogue, although that would be helpful. 
};

But it did not work. 但它没有用。 Then I've read here: How to execute ajax function onbeforeunload? 然后我在这里读到: 如何在onbeforeunload上执行ajax函数? that the request needs to be synchronous and here: How to $http Synchronous call with AngularJS that Angular does not support this (although this one might be outdated). 请求需要同步,这里: 如何$ http与AngularJS同步调用 ,Angular不支持这个(虽然这可能已经过时)。

I've also tried calling $http directly (without the service) but that did not work either. 我也试过直接调用$ http(没有服务),但这也不起作用。 At this point I'm stuck. 此时我被困住了。 Any suggestions / leads would be really appreciated. 任何建议/线索将非常感激。

Thanks in advance! 提前致谢!

The problem is that angular always make ASYNCHRONOUS calls with the $http service (and you can't change that behavior). 问题是angular总是使用$ http服务进行ASYNCHRONOUS调用(并且你无法改变这种行为)。 Since the page exits before the $http service have a chance to emit the requests you are not getting the desired result. 由于页面在$ http服务有机会发出请求之前退出,因此无法获得所需的结果。

If you want a workarround without using any third party libraries try the following code: 如果您想要一个不使用任何第三方库的workarround,请尝试以下代码:

var onBeforeUnload = function () {

    var data = angular.toJson($scope.id...);//make sure you $scope is legal here...
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST", "apiURL/unlock", false);//the false is for making the call synchronous
    xmlhttp.setRequestHeader("Content-type", "application/json");
    xmlhttp.setRequestHeader("Authorization", token);
    xmlhttp.send(data);
}

It will block UI until the request is completed, so try to make the server fast or the user will notice. 它将阻止UI直到请求完成,因此尝试使服务器快速或用户会注意到。

Solution is to call $rootScope.$digest(); 解决方法是调用$rootScope.$digest(); after firing your $http calls in your onbeforeunload callback. 在你的onbeforeunload回调中触发$http调用之后。 The reason is that angular's $http methods wrap the config in an immediately resolved promise which means the ajax request doesn't actually get fired until the next tick. 原因是angular的$http方法将配置包装在一个立即解决的promise中,这意味着ajax请求实际上不会被触发,直到下一个tick。 Other browsers appear to allow one more tick after the onbeforeunload tick, but not IE11 (the only version of IE in which I tested). 其他浏览器在onbeforeunload tick之后似乎允许多一个tick,而不是IE11(我测试的IE的唯一版本)。 Forcing the digest cycle avoids the need to wait until the next tick. 强制摘要周期避免了等到下一个滴答的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM