当前一页具有不同的主机名时,限制页面重定向的最佳方法是什么?

时间:2016-02-10 11:01:16

标签: javascript angularjs

我正在研究一种角度SPA。我遇到过一种情况,我需要限制返回上一页或操纵相同的内容。

情景1:

URL 1: Landing page
    www.myapp.com/citizen/#/wizard/introduction

URL 2: User goes to login page
    www.myapp.com/citizen/#/wizard/login

URL 3: Login button redirect to third party service
    www.thirdpartylogin.com/login

URL 4: After successful login it redirects to 
    www.myapp.com/citizen/#/wizard/home

当用户现在点击后退按钮时,我不希望用户转到URL 3.如果我将用户带到URL 3或URL 2,用户应该保留在URL 4上,甚至可以保留其罚款。

情景2:

URL 1: Home page
    www.myapp.com/citizen/#/wizard/home

URL 2: User goes to third party payment page
    www.thirdpartypayment.com/payment

URL 3: Finish
    www.myapp.com/citizen/#/wizard/finish

在这种情况下,我不希望用户转到付款页面并继续使用URL 3。

有没有办法限制或操纵场景1和场景2的浏览器后退按钮?

3 个答案:

答案 0 :(得分:1)

我会通过在第三方服务登陆后添加一个步骤来实现:

dataMod.manage("data/registries.json", "load").then(function(response){
  $scope.data = response.data //different object structure than for success, then receives the whole response together with headers, success receives only response.data
})

通过这种方式,每当你返回表单url 4时,你将被重定向到url 4本身。如果要更改行为,可以在重定向之前在URL 3.5中使用history.pushState()

答案 1 :(得分:0)

您可以尝试禁用浏览器后退按钮

页面加载:

  function disableBack() { 
        window.history.forward();
  }

   window.onload = disableBack();

在页面加载:

history.pushState(null, null, 'pagename');

  window.addEventListener('popstate', function(event) {
      history.pushState(null, null, 'pagename');
  });

参考链接:

答案 2 :(得分:0)

更改第三方重定向

如果您可以控制从第三方到您的应用程序的重定向是如何完成的,您可以更改它,以便它使用javascript进行重定向:

window.location.replace(newLocation);

它将使用后面历史记录中的新位置替换当前位置。

使用iframe

在大多数情况下,您将无法访问服务源代码(除非您自己开发),因此您必须创建一个页面,在iframe中显示第三方服务。

URL 1: Landing page
    www.myapp.com/citizen/#/wizard/introduction

URL 2: User goes to login page
    www.myapp.com/citizen/#/wizard/login

URL 2bis: Login button displays the third party service in an iframe (user is still on your application)

现在您想知道iframe内的位置何时发生变化(即登录/付款完成且服务重定向到您的应用时)。要使用angular执行此操作,您需要创建一个简单的指令来监视iframe上的load事件:

APP.directive('iframeOnload', [function(){
    return {
        scope: {
            callBack: '&iframeOnload'
        },
        link: function(scope, element, attrs){
            element.on('load', function(){
                return scope.callBack();
            })
        }
    }}])

并像这样使用它:

<iframe class="gds-taskform-iframe" height="1000" width="100%" iframe-on-load="myRedirect()" ng-src="{{ serviceUrl }}"></iframe>

这是控制器代码

APP.controller('testController', function ($sce, $scope, $location){
        var firstLoad = true;
        $scope.serviceUrl = $sce.trustAsResourceUrl("https://www.univ-smb.fr/");

        $scope.myRedirect = function(){
            if(!firstLoad){
                window.location.replace('http://google.com');
            }
            firstLoad = false;
        };
    });

请注意,我使用布尔值来检查这是否是iframe的第一个加载事件。如果我不这样做,它将在第一次加载第三方服务时启动重定向。

这是完整的工作代码

<!Doctype html>
<html ng-app="test">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />

        <!-- angular -->
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
    </head>
    <body>      
        <div class="container-fluid" ng-controller="testController">
            <iframe height="1000" width="100%" iframe-onload="myRedirect()" ng-src="{{ serviceUrl }}"></iframe>
        </div>
    </body>
    <script>
        var APP = angular.module('test', []);

        APP.directive('iframeOnload', [function(){
        return {
            scope: {
                callBack: '&iframeOnload'
            },
            link: function(scope, element, attrs){
                element.on('load', function(){
                    return scope.callBack();
                })
            }
        }}])

        APP.controller('testController', function ($sce, $scope, $location){
            var firstLoad = true;
            $scope.serviceUrl = $sce.trustAsResourceUrl("https://www.univ-smb.fr/");

            $scope.myRedirect = function(){
                if(!firstLoad){
                    window.location.replace('http://google.com');
                }
                firstLoad = false;
            };
        });
    </script>
</html>

请注意,您可以遇到拒绝在框架中显示“http://serviceurl/”,因为如果服务的作者不需要您,则将“X-Frame-Options”设置为“SAMEORIGIN”在iframe中使用它。