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

lau*_*iad 179 angularjs angular-routing

我的印象是Angular会重写在tempaltes中的锚标记的href属性中出现的URL,这样无论是在html5模式还是hashbang模式下它们都能正常工作.位置服务文档似乎说HTML链接重写处理了hashbang情况.因此,我希望在不在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>
Run Code Online (Sandbox Code Playgroud)

附录:在重新阅读我的问题时,我发现我使用了"重写"一词,但没有明确说明我何时以及何时进行重写.问题是如何让Angular在呈现路径时重写URL,以及如何在两种模式下统一解释JS代码中的路径.它不是关于如何使Web服务器执行HTML5兼容的请求重写.

小智 359

关于AngularJS路由的文档不是很清楚.它讨论了Hashbang和HTML5模式.事实上,AngularJS路由以三种模式运行:

  • 哈什邦模式
  • HTML5模式
  • Hashbang在HTML5模式下

对于每个模式,存在相应的LocationUrl类(LocationHashbangUrl,LocationUrl和LocationHashbangInHTML5Url).

为了模拟URL重写,你必须实际将html5mode设置为true并装饰$ sniffer类,如下所示:

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});
Run Code Online (Sandbox Code Playgroud)

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

哈什邦模式

组态:

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
});
$locationProvider
  .html5Mode(false)
  .hashPrefix('!');
Run Code Online (Sandbox Code Playgroud)

当您需要在HTML文件中使用带有哈希的URL时就是这种情况

<a href="index.html#!/path">link</a>
Run Code Online (Sandbox Code Playgroud)

在浏览器中,您必须使用以下链接: http://www.example.com/base/index.html#!/base/path

正如您在纯Hashbang模式中看到的那样,HTML文件中的所有链接都必须以基数开头,例如"index.html#!".

HTML5模式

组态:

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);
Run Code Online (Sandbox Code Playgroud)

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

<html>
  <head>
    <base href="/">
  </head>
</html>
Run Code Online (Sandbox Code Playgroud)

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

<a href="/path">link</a>
Run Code Online (Sandbox Code Playgroud)

浏览器链接:

http://www.example.com/base/path
Run Code Online (Sandbox Code Playgroud)

Hashbang在HTML5模式下

当我们实际使用HTML5模式但在不兼容的浏览器中时,此模式被激活.我们可以通过修改$ sniffer服务并将历史记录设置为false来在兼容的浏览器中模拟此模式.

组态:

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

在HTML文件中设置基数:

<html>
  <head>
    <base href="/">
  </head>
</html>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,链接也可以在HTML文件中没有散列的情况下编写

<a href="/path">link</a>
Run Code Online (Sandbox Code Playgroud)

浏览器链接:

http://www.example.com/index.html#!/base/path
Run Code Online (Sandbox Code Playgroud)


Mis*_*lis 8

对于未来的读者,如果您使用的是Angular 1.6,您还需要更改hashPrefix:

appModule.config(['$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('');
}]);
Run Code Online (Sandbox Code Playgroud)

不要忘记在HTML中设置基数<head>:

<head>
    <base href="/">
    ...
</head>
Run Code Online (Sandbox Code Playgroud)

有关changelog的更多信息here.

  • 谢谢@Mistalis.你的答案很好.但是当我在路由后刷新页面时发生问题,发现页面未找到错误.请帮我.. (3认同)