AngularJS HTML5模式降级为完整页面重新加载,以代替hashbang
通过在AngularJS中启用HTML5模式,AngularJS HTML5模式降级为完整页面重新加载,以代替hashbang,angularjs,Angularjs,通过在AngularJS中启用HTML5模式,$location服务将重写URL以删除其中的hashbang。这是一个很好的特性,可以帮助我使用我的应用程序,但是它的回退到hashbang模式有一个问题。我的服务需要身份验证,我被迫从应用程序使用外部身份验证机制。如果用户试图转到包含hashbang的我的应用程序的URL,它将首先将他们重定向到身份验证页面(除非成功验证,否则永远不会接触我的服务),然后将他们重定向回我的应用程序。由于散列标记只能从客户端看到,所以当路由到达我的服务器时,它将从路
$location
服务将重写URL以删除其中的hashbang。这是一个很好的特性,可以帮助我使用我的应用程序,但是它的回退到hashbang模式有一个问题。我的服务需要身份验证,我被迫从应用程序使用外部身份验证机制。如果用户试图转到包含hashbang的我的应用程序的URL,它将首先将他们重定向到身份验证页面(除非成功验证,否则永远不会接触我的服务),然后将他们重定向回我的应用程序。由于散列标记只能从客户端看到,所以当路由到达我的服务器时,它将从路由的任何部分脱落。一旦他们通过身份验证,他们可能会重新输入URL,它就会工作,但这是一个初始时间,将导致用户体验中断
那么,我的问题是,有没有办法从$location.html5Mode(true)
过渡到对不支持的浏览器重新加载整个页面,从而完全跳过AngularJS中的hashbang路由方法
与我的目标相比较,最好的方法是浏览github.com上的文件夹。如果浏览器支持在不启动页面刷新的情况下重写URL,则页面将异步加载必要的部分。如果浏览器不支持它,当用户单击文件夹时,将刷新整个页面。这可以用AngularJS代替hashbang模式实现吗?尝试在浏览器的HTML5历史API检查中包装$location和$routeProvider配置,如下所示:
if (isBrowserSupportsHistoryAPI()) {
$location.html5Mode(true)
$routeProvider.when(...);
}
如果使用$location更改路径,还可能需要创建$location的包装。
(抱歉,英语太糟糕了)对于这种情况,为什么不在客户端处理未经身份验证的重定向?我需要更多地了解你的应用程序是如何工作的,以便为你提供更具体的解决方案,但本质上类似于:
module('app',[])
.configure(...yadda...yadda...yadda...)
.run(['$location', 'authenticationService', function($location, auth) {
if (!auth.isAuthenticated()) {
$location.url(authenticationUrl)
}
});
我已经加入了一个服务,它会发现你是否以某种方式通过了身份验证,取决于你如何检查会话cookie,是否可以点击你的API询问。这取决于在客户端应用程序运行时,您希望如何继续检查身份验证。您可以尝试覆盖$location服务的功能。一般的想法是根据是否有人已经通过身份验证来重写URL,或者对所有URL使用单一方法(不带hashbang),而不管html5mode是否启用 我不确定我是否完全理解用例,因此我无法编写您需要的确切代码。下面是如何覆盖/实现和注册$location服务的示例实现,只需确保hashbang总是被消除:
app.service('$location', [function() {
var DEFAULT_PORTS = {
ftp: 21,
http: 80,
https: 443
};
angular.extend(this, {
absUrl: function() {
return location.href;
},
hash: function(hash) {
return location.hash.substr(1);
},
host: function() {
return location.host;
},
path: function(path) {
if (!path) {
return location.pathname;
}
location.pathname = path;
return this;
},
port: function() {
return location.port ? Number(location.port) : DEFAULT_PORTS[this.protocol()] || null;
},
protocol: function() {
return location.protocol.substr(0, location.protocol.length - 1);
},
replace: function() {
return this;
},
search: function(search, paramValue) {
if (search || paramValue) {
return this;
}
var query = {};
location.search.substr(1).split("&").forEach(function(pair) {
pair = pair.split("="); query[pair[0]] = decodeURIComponent(pair[1]);
});
return query;
},
url: function(url, replace) {
return this.path();
}
});
}]);
不要覆盖核心功能 使用Modernizer,进行特征检测,然后进行相应的处理 检查历史API支持情况
if (Modernizr.history) {
// history management works!
} else {
// no history support :(
// fall back to a scripted solution like History.js
}
你有没有想出解决这个问题的办法?我面临着类似的情况。