我正在研究一种角度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的浏览器后退按钮?
答案 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中显示第三方服务。
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中使用它。