我的印象是Angular会重写模板中锚标签的href属性中的url,这样它们就可以在html5模式或hashbang模式下工作。位置服务的文档似乎说HTML链接重写会处理散列的情况。因此,我希望当不在HTML5模式下时,将插入哈希值,而在HTML5模式下,它们不会。
然而,似乎没有重写发生。下面的示例不允许我只更改模式。应用程序中的所有链接都需要手工重写(或在运行时从变量派生)。我是否需要根据模式手动重写所有url ?
在Angular 1.0.6、1.1.4或1.1.3中,我没有看到任何客户端url重写。似乎所有的href值都需要在hashbang模式前加上#/,在html5模式前加上/。
是否需要一些配置来导致重写?我是不是看错了医生?做其他傻事?
下面是一个小例子:
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.3/angular.js"></script>
</head>
<body>
<div ng-view></div>
<script>
angular.module('sample', [])
.config(
['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
//commenting out this line (switching to hashbang mode) breaks the app
//-- unless # is added to the templates
$locationProvider.html5Mode(true);
$routeProvider.when('/', {
template: 'this is home. go to <a href="/about"/>about</a>'
});
$routeProvider.when('/about', {
template: 'this is about. go to <a href="/"/>home</a'
});
}
])
.run();
</script>
</body>
附录:在重读我的问题时,我发现我使用了"重写"一词,但没有清楚地说明我想在谁和什么时候进行重写。这个问题是关于如何获得Angular如何在渲染路径时重写url,以及如何让它跨两种模式统一地解释JS代码中的路径。它是而不是关于如何让web服务器重写兼容html5的请求。
文档对AngularJS的路由并不是很清楚。它谈到了Hashbang和HTML5模式。实际上,AngularJS的路由有三种模式:
<<ul>每种模式都有一个各自的LocationUrl类(LocationHashbangUrl, LocationUrl和LocationHashbangInHTML5Url)。
为了模拟URL重写,你必须将html5mode设置为true,并按照如下方式修饰$sniffer类:
$provide.decorator('$sniffer', function($delegate) {
$delegate.history = false;
return $delegate;
});
我现在将更详细地解释:
<标题>Hashbang模式配置:
$routeProvider
.when('/path', {
templateUrl: 'path.html',
});
$locationProvider
.html5Mode(false)
.hashPrefix('!');
当您需要在HTML文件中使用带有散列的url时,例如
<a href="index.html#!/path">link</a>
在浏览器中,您必须使用以下链接:http://www.example.com/base/index.html#!/base/path
可以看到,在纯Hashbang模式下,HTML文件中的所有链接都必须以"index.html#!"这样的基开头。
<标题>HTML5模式配置:
$routeProvider
.when('/path', {
templateUrl: 'path.html',
});
$locationProvider
.html5Mode(true);
你应该在HTML-file
中设置基<html>
<head>
<base href="/">
</head>
</html>
在这种模式下,你可以在HTML文件中使用没有#的链接
<a href="/path">link</a>
浏览器链接:
http://www.example.com/base/path
HTML5模式下的Hashbang
当我们实际使用HTML5模式,但在一个不兼容的浏览器中,此模式被激活。我们可以通过修饰$sniffer服务并将历史记录设置为false来在兼容的浏览器中模拟此模式。
配置:
$provide.decorator('$sniffer', function($delegate) {
$delegate.history = false;
return $delegate;
});
$routeProvider
.when('/path', {
templateUrl: 'path.html',
});
$locationProvider
.html5Mode(true)
.hashPrefix('!');
设置基础在HTML-file:
<html>
<head>
<base href="/">
</head>
</html>
在这种情况下,链接也可以在HTML文件
中不使用哈希值。<a href="/path">link</a>
浏览器链接:
http://www.example.com/index.html#!/base/path
标题>标题>对于未来的读者,如果你正在使用Angular 1.6,您还需要更改hashPrefix
:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('');
}]);
不要忘记在你的HTML设置基础<head>
:
<head>
<base href="/">
...
</head>
关于变更日志的更多信息在这里.
这花了我一段时间来弄清楚,所以这就是我是如何让它工作的- Angular WebAPI ASP Routing没有# for SEO
- add to Index.html - base href="/">
-
添加locationProvider.html5Mode美元(真正的);app.config
-
我需要一个特定的控制器(在home控制器中)在上传图像时被忽略,所以我将该规则添加到routecconfig
routes.MapRoute( name: "Default2", url: "Home/{*.}", defaults: new { controller = "Home", action = "SaveImage" } );
-
在全球。请添加以下内容-确保忽略API和图像上传路径,让它们正常运行,否则将重新路由其他所有内容。
private const string ROOT_DOCUMENT = "/Index.html"; protected void Application_BeginRequest(Object sender, EventArgs e) { var path = Request.Url.AbsolutePath; var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase); var isImageUpload = path.StartsWith("/home", StringComparison.InvariantCultureIgnoreCase); if (isApi || isImageUpload) return; string url = Request.Url.LocalPath; if (!System.IO.File.Exists(Context.Server.MapPath(url))) Context.RewritePath(ROOT_DOCUMENT); }
-
确保使用$location.url('/XXX')而不是window。位置……重定向
-
使用绝对路径引用CSS文件
和
<link href="app/content/bootstrapwc.css" rel="stylesheet" />
最后注意-这样做给了我完全的控制,我不需要对web配置做任何事情。
希望这对我有帮助,因为我花了一段时间才弄明白。
我希望能够使用HTML5模式和固定令牌访问我的应用程序,然后切换到hashbang方法(保留令牌,以便用户可以刷新他的页面)。
访问我的应用的URL:
http://myapp.com/amazing_url?token=super_token
当用户加载页面时:
http://myapp.com/amazing_url?token=super_token#/amazing_url
当用户导航时:
http://myapp.com/amazing_url?token=super_token#/another_url
这样,我将令牌保留在URL中,并保留用户浏览时的状态。我失去了一点URL的可见性,但没有完美的方法来做到这一点。
所以不要启用HTML5模式然后添加这个控制器:
.config ($stateProvider)->
$stateProvider.state('home-loading', {
url: '/',
controller: 'homeController'
})
.controller 'homeController', ($state, $location)->
if window.location.pathname != '/'
$location.url(window.location.pathname+window.location.search).replace()
else
$state.go('home', {}, { location: 'replace' })