$ location / html5和hashbang模式/链接重写之间的切换

我的印象是,Angular会重写出现在临时标签内的锚标签的href属性中的URL,使得它们可以在html5模式或hashbang模式下工作。 位置服务的文档似乎说HTML链接重写照顾的hashbang的情况。 因此,我期望在不使用HTML5模式时,插入哈希值,而在HTML5模式下,则不会。

但是,似乎没有重写正在发生。 下面的例子不允许我改变模式。 应用程序中的所有链接都需要手动重写(或者在运行时从variables派生出来)。我是否需要根据模式手动重写所有URL?

我没有看到在Angular 1.0.6,1.1.4或1.1.3中有任何客户端的URL重写。 似乎所有的href值都需要用#/作为hashbang模式和/ html5模式。

是否有一些configuration需要重写? 我误解了文档吗? 做别的事情傻吗?

这是一个小例子:

<head> <script src="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在渲染path时重写URL,以及如何在两种模式下统一解释JS代码中的path。 这不是关于如何使Web服务器执行与HTML5兼容的重写请求。

关于AngularJS路由的文档不是很清楚。 它谈到Hashbang和HTML5模式。 事实上,AngularJS路由有三种模式:

  • 哈希邦模式
  • HTML5模式
  • 在HTML5模式下的Hashbang

对于每种模式,都有一个相应的LocationUrl类(LocationHashbangUrl,LocationUrl和LocationHashbangInHTML5Url)。

为了模拟URL重写,你必须实际设置html5mode为true,并装饰$嗅探器类如下:

 $provide.decorator('$sniffer', function($delegate) { $delegate.history = false; return $delegate; }); 

现在我将更详细地解释这一点:

哈希邦模式

组态:

 $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/pathhttp://www.example.com/base/index.html#!/base/path base/ http://www.example.com/base/index.html#!/base/path

正如你所看到的,在纯粹的Hashbang模式下,HTML文件中的所有链接都必须以“index.html#!”为底。

HTML5模式

组态:

 $routeProvider .when('/path', { templateUrl: 'path.html', }); $locationProvider .html5Mode(true); 

您应该在HTML文件中设置基础

 <html> <head> <base href="/"> </head> </html> 

在这种模式下,您可以使用HTML文件中没有#的链接

 <a href="/path">link</a> 

浏览器链接:

 http://www.example.com/base/path 

在HTML5模式下的Hashbang

当我们实际使用HTML5模式,但在不兼容的浏览器中时,此模式被激活。 我们可以通过装饰$嗅探器服务并将历史logging设置为false来在兼容的浏览器中模拟此模式。

组态:

 $provide.decorator('$sniffer', function($delegate) { $delegate.history = false; return $delegate; }); $routeProvider .when('/path', { templateUrl: 'path.html', }); $locationProvider .html5Mode(true) .hashPrefix('!'); 

在HTML文件中设置基础:

 <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路由没有#为SEO

  1. 添加到Index.html – base href =“/”>
  2. 添加$ locationProvider.html5Mode(true); 到app.config

  3. 我需要一个特定的控制器(这是在家里的控制器)被忽略的上传图像,所以我把这个规则添加到RouteConfig

      routes.MapRoute( name: "Default2", url: "Home/{*.}", defaults: new { controller = "Home", action = "SaveImage" } ); 
  4. 在Global.asax中添加以下内容 – 确保忽略api和图像上传path,让它们正常工作,否则重新路由其他所有内容。

      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); } 
  5. 确保使用$ location.url('/ XXX')而不是window.location …来redirect

  6. 使用绝对path引用CSS文件

并不是

 <link href="app/content/bootstrapwc.css" rel="stylesheet" /> 

最后的注意事项 – 这样做给了我完全的控制,我不需要做任何事情的networkingconfiguration。

希望这有帮助,因为这花了我一段时间弄清楚。

我希望能够使用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' })