$location / switching between html5 and hashbang mode / link rewriting Ask Question

$location / switching between html5 and hashbang mode / link rewriting Ask Question

I was under the impression that Angular would rewrite URLs that appear in href attributes of anchor tags within tempaltes, such that they would work whether in html5 mode or hashbang mode. The documentation for the location service seems to say that HTML Link Rewriting takes care of the hashbang situation. I would thus expect that when not in HTML5 mode, hashes would be inserted, and in HTML5 mode, they would not.

However, it seems that no rewriting is taking place. The following example does not allow me to just change the mode. All links in the application would need to be rewritten by hand (or derived from a variable at runtime. Am I required to manually rewrite all URLs depending on the mode?

I don't see any client-side url rewriting going on in Angular 1.0.6, 1.1.4 or 1.1.3. It seems that all href values need to be prepended with #/ for hashbang mode and / for html5 mode.

Is there some configuration necessary to cause rewriting? Am I misreading the docs? Doing something else silly?

Here's a small example:

<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>

Addendum: in re-reading my question, I see that I used the term "rewriting" without an abundance of clarity as to who and when I wanted to do the rewriting. The question is about how to get Angular to rewrite the URLs when it renders paths and how to get it to interpret paths in the JS code uniformly across the two modes. It is not about how to cause a web server to do HTML5-compatible rewriting of requests.

ベストアンサー1

The documentation is not very clear about AngularJS routing. It talks about Hashbang and HTML5 mode. In fact, AngularJS routing operates in three modes:

  • Hashbang Mode
  • HTML5 Mode
  • Hashbang in HTML5 Mode

For each mode there is a a respective LocationUrl class (LocationHashbangUrl, LocationUrl and LocationHashbangInHTML5Url).

URL 書き換えをシミュレートするには、実際に html5mode を true に設定し、$sniffer クラスを次のように装飾する必要があります。

$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/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 モードを使用しているが、互換性のないブラウザで使用している場合、アクティブになります。$sniffer サービスを装飾し、履歴を 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

おすすめ記事