AngularJS1.6に上げたらルーティング時のパスがhash (#/)からhash-bang (#!/)になっていた

AngularJS1.6に上げたらルーティング時のパスがhash (#/)からhash-bang (#!/)になっていた

自己学習用に作成していたAngularJS 1.4アプリをAngularJS 1.6 に上げた際に、 ルーティング時のパスがhash #/ からhash-bang #!/ に変換されるようになってしまい、うまくルーティングが働かなくなってしまう問題に遭遇しました。 対応したのでメモとして残しておきます。

現象

以下のURLに直接またはリンクから遷移しようとしたとき、例えば以下のような

http://localhost:9000/#/search

にすると、ルーティング定義したページを表示して欲しいのですが、

http://localhost:9000/#!/#%2Fsearch

上記のように自動的にスラッシュが %2F 変換され、hash-bang #!/ が追加されます。 自分の環境では、上記のURLはルーティング定義していないので、 otherwise に設定しているページに遷移されるようになってしまいました。

ちなみに、ルーティングの定義は以下のように行っています。

.when('/search', {
  templateUrl: 'views/search.html',
  controller: 'SearchCtrl',
  controllerAs: 'search'
})
.otherwise({
  redirectTo: '/'
});

原因

AngularJS 1.6が $location サービスのURLのデフォルト値を変更したことが原因です。

Googleクローラー対策みたいです。(#!/を使用することを推奨している。)

ちなみに、以下のコミットで修正されています。 https://github.com/angular/angular.js/commit/aa077e81129c740041438688dff2e8d20c3d7b52

解決方法1

リンクのURLの#のあとに!を加えるようにします。 これが一番素直な解決方法かと。私はこちらで対応しています。

<a ng-href="#/search">Search</a>

を以下のように#/#!/にしてあげます。

<a ng-href="#!/search">Search</a>

解決方法2

AngularJS 1.6 以前と同じく #/ でいけるようにするには、 $locationProvider.hashPrefix('') を設定することで対応できます。

appModule.config(['$locationProvider', function($locationProvider) {
  $locationProvider.hashPrefix('');
}]);

参考

https://docs.angularjs.org/guide/migration#commit-aa077e8 https://github.com/angular/angular.js/commit/aa077e81129c740041438688dff2e8d20c3d7b52 http://stackoverflow.com/questions/41211875/angularjs-1-6-0-latest-now-routes-not-working http://stackoverflow.com/questions/41272314/angular-all-slashes-in-url-changed-to-2f