AngularJSのURLからフラグメント識別子を削除する(#記号)


257

angular.jsのURLから#記号を削除することはできますか?

ビューを変更してURLをパラメーターで更新するときに、ブラウザーの戻るボタンなどを引き続き使用できるようにしたいのですが、#記号は必要ありません。

チュートリアルrouteProviderは次のように宣言されています。

angular.module('phonecat', []).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
  when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
  when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
  otherwise({redirectTo: '/phones'});
}]);

#なしで同じ機能を持つようにこれを編集できますか?


13
ハッシュタグ nice one
BoJack Horseman 2014


私にとって、ここでのすべての答えは間違っています。URLを「書き換え」て#を削除できますが、#なしでWebページに直接アクセスすることはできません。ここで実際の解決策はありますか?
amdev

Angular 1.6を使用している場合の解決策は次のとおりです。
Mistalis 2017年

回答:


251

はい、構成$locationProviderして設定html5Modeする必要がありますtrue

angular.module('phonecat', []).
  config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {

    $routeProvider.
      when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});

    $locationProvider.html5Mode(true);

  }]);

10
ので、IE 10は、LTの設定で有効にされたHTML5履歴APIをサポートしていませんhtml5Mode(true)。IEでは#、ルートで使用する必要があります。
Maxim Grach 2013

10
@powtac IE lt 10は、Internet Explorerがバージョン10未満であることを意味します
Maxim Grach

6
IEで#を使用するようにフォールバックできるように設定できますか?それだけで包むような単純なようである$locationProvider.html5Mode(true);if !(IE lt 10)
アンディヘイデン

52
したがって、このソリューションは、URLにハッシュタグがある場合、URL内のハッシュタグの削除を解決しますが、最初にハッシュタグを含めたくない要求に応答する方法を解決しません。別名、blah /#/ phones- > blah / phonesを解決しますが、blah / phonesを直接処理しません。
ルーク

9
<base href = "/" />をindex.htmlの<head>セクションに配置する必要がありました。
nyxz

55

html5履歴APIのブラウザーサポートを確認してください。

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }

23
これは質問に直接回答しないため、コメントとして適しています。
brandonscript 2013

31
開発者ガイドによると、この検出は自動的に行われます:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB

チャームのように機能しました。ブラウザのバージョンチェックではなくメソッドチェックに感謝します。
シェーン2014年

46

ハッシュタグを削除するにはかなりのURLともあなたのために縮小した後の仕事へのコードあなたは、以下の例のようにコードを構造化する必要があります。

jobApp.config(['$routeProvider','$locationProvider',
    function($routeProvider, $locationProvider) {
        $routeProvider.
            when('/', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus/:id', {
                templateUrl: 'views/job-detail.html',
                controller: 'JobDetailController'
            });

         //you can include a fallback by  including .otherwise({
          //redirectTo: '/jobs'
        //});


        //check browser support
        if(window.history && window.history.pushState){
            //$locationProvider.html5Mode(true); will cause an error $location in HTML5 mode requires a  tag to be present! Unless you set baseUrl tag after head tag like so: <head> <base href="https://stackoverflow.com/">

         // to know more about setting base URL visit: https://docs.angularjs.org/error/$location/nobase

         // if you don't wish to set base URL then use this
         $locationProvider.html5Mode({
                 enabled: true,
                 requireBase: false
          });
        }
    }]);

15
以下のためのrequireBase: false1
whoan

2
@digitlimit様、$locationProvider.html5Modeコードを追加した後、コード$urlRouterProvider.otherwise('/home');が機能しなくなりました。
Jaikrat

18

$locationProvider.html5Mode(true)で設定した後、web.configにルールを書き込みapp.jsます。

誰かが助けてくれることを願っています。

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

私のindex.htmlでこれを追加しました <head>

<base href="/">

サーバーにiis用のURLリライターをインストールすることを忘れないでください。

また、Web APIとIISを使用する場合、API呼び出しが変更されるため、この一致URLは機能しません。したがって、3番目の入力(条件の3行目)を追加し、からの呼び出しを除外するパターンを指定しますwww.yourdomain.com/api


1
IISのURLリライタはどのようにインストールしますか?Azureでホスティングしています。
Prabhu 2015年

11

AngularJSを使用したMVCで.NETスタックを使用している場合、URLから「#」を削除するには、次のようにする必要があります。

  1. _Layoutページでbase hrefを設定します。 <head> <base href="https://stackoverflow.com/"> </head>

  2. 次に、角度のアプリ構成に以下を追加します: $locationProvider.html5Mode(true)

  3. 上記はURLから「#」を削除しますが、ページの更新は機能しません。たとえば、「yoursite.com/about」にいる場合、ページのrefreashは404を提供します。これは、MVCが角度ルーティングとMVCパターンによって認識しないためですMVCルーティングパスに存在しない「about」のMVCページを探します。これの回避策は、すべてのMVCページリクエストを単一のMVCビューに送信することです。

url:

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);

どのファイルにroutes.MapRouteを追加する必要がありますか?
Vicheanak 2015年

1
RouteConfig.csのApp_Startフォルダー下
Maksood

5

html5モードを微調整できますが、これは、ページのHTMLアンカーに含まれるリンクと、ブラウザのアドレスバーでのURLの外観にのみ機能します。ページの外側からハッシュタグなし(html5modeの有無にかかわらず)でサブページをリクエストしようとすると、404エラーが発生します。たとえば、次のCURLリクエストでは、html5modeに関係なく、ページが見つからないというエラーが発生します。

$ curl http://foo.bar/phones

ただし、以下はルート/ホームページを返します。

$ curl http://foo.bar/#/phones

これは、リクエストがサーバーに到着する前に、ハッシュタグの後のものが取り除かれるからです。したがって、のリクエストはのリクエストとしてhttp://foo.bar/#/portfolioサーバーに到着しますhttp://foo.bar。サーバーは(おそらく)200 OK応答で応答http://foo.barし、エージェント/クライアントは残りを処理します。

したがって、URLを他のユーザーと共有したい場合は、ハッシュタグを含めるしかありません。


これを回避する方法はありませんか?これはかなり大きな問題です。
user441521

5

2つの手順に従ってください。1
.まず、アプリの構成ファイルで$ locationProvider.html5Mode(true)を設定します。
たとえば-
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2.次に、メインページ内に<base>を設定します。
例えば->
<base href="https://stackoverflow.com/">

$ locationサービスは、HTML5 History APIをサポートしないブラウザーのハッシュパートメソッドに自動的にフォールバックします。


3

私の解決策は、.htaccessを作成し、#Sorianコードを使用することです。.htaccessなしで、削除に失敗しました#

RewriteEngine   On
RewriteBase     /
RewriteCond     %{REQUEST_URI} !^(/index\.php|/img|/js|/css|/robots\.txt|/favicon\.ico)
RewriteCond     %{REQUEST_FILENAME} !-f
RewriteCond     %{REQUEST_FILENAME} !-d
RewriteRule     ./index.html [L]

1

ドキュメントによると。以下を使用できます。

$locationProvider.html5Mode(true).hashPrefix('!');

注意:ブラウザがHTML 5をサポートしていない場合は、心配しないでください:Dハッシュバングモードにフォールバックします。したがって、if(window.history && window.history.pushState){ ... }手動で確認する必要はありません

例:クリックすると: <a href="https://stackoverflow.com/other">Some URL</a>

HTML5ブラウザでは、 angularは自動的にリダイレクトされますexample.com/other

HTML5以外のブラウザでは、 angularは自動的にリダイレクトされますexample.com/#!/other


1

この回答は、nginxをリバースプロキシとして使用しており、すでに$ locationProvider.html5modeをtrueに設定していることを前提としています。

->上記のすべてのクールなものでまだ苦労しているかもしれない人々のために。

確かに、@ maxim grachソリューションは問題なく機能しますが、ハッシュタグを最初に含めたくないリクエストに応答する方法のソリューションとしては、phpが404を送信しているかどうかを確認してから、URLを書き換えます。以下はnginxのコードです、

phpの場所で、404 phpエラーを検出し、別の場所にリダイレクトします。

location ~ \.php${
  ...
  fastcgi_intercept_errors on;
  error_page 404 = /redirect/$request_uri ;
}

次に、リダイレクトの場所でURLを書き換えて、データをプロキシ渡しし、offcourse、ブログのURLの場所にWebサイトのURLを配置します。(リクエスト:試してから質問してください)

location /redirect {
  rewrite ^/redirect/(.*) /$1;
  proxy_pass http://www.techromance.com;
}

そして魔法を見てください。

そして、それは間違いなく機能します。少なくとも私にとっては。


これをどこに追加しますか?
Volatil3 2017年

上記のコードをどこに追加しますか?それらをメインのNginx設定ファイルに入れます。
Satys 2017年

1

index.htmlから開始し、すべて#を削除する<a href="#/aboutus">About Us</a>ので、<a href="https://stackoverflow.com/aboutus">About Us</a>.Now.indexのヘッドタグで<base href="https://stackoverflow.com/">最後のメタタグの直後に書き込む必要があります。

今あなたのルーティングjsに注入し$locationProvider$locatonProvider.html5Mode(true); このような何かを書く:-

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when("/home", {
            templateUrl: "Templates/home.html",
            controller: "homeController"
        })
            .when("/aboutus",{templateUrl:"Templates/aboutus.html"})
            .when("/courses", {
                templateUrl: "Templates/courses.html",
                controller: "coursesController"
            })
            .when("/students", {
                templateUrl: "Templates/students.html",
                controller: "studentsController"
            })
        $locationProvider.html5Mode(true);
    });

詳細については、このビデオを ご覧くださいhttps://www.youtube.com/watch?v=XsRugDQaGOo


#URLを削除せずにテストしていたため、#URLをすべて削除すると役に立ちました。
optimistanoop

1

これは本当に遅いと思います。しかし、以下の設定をapp.module importsに追加するとうまくいきます:

RouterModule.forRoot(routes, { useHash: false })

0

ステップ1:$ locationProviderサービスをアプリ構成のコンストラクターに挿入する

ステップ2:アプリの設定のコンストラクターにコード行$ locationProvider.html5Mode(true)を追加します。

ステップ3:コンテナー(ランディング、マスター、またはレイアウト)ページで<base href="https://stackoverflow.com/">、タグ内などにhtmlタグを追加します。

手順4:すべてのアンカータグからルーティング構成のすべての「#」を削除します。たとえば、href = "#home"はhref = "home"になり、href = "#about"はherf = "about"になります; href = "#contact 「href = "contact"になります」

 <ul class="nav navbar-nav">
     <li><a href="home">Home</a></li>
     <li><a href="about">About us</a></li>
     <li><a href="contact">Contact us</a></li>
</ul>

-1

ただ、追加$locationProviderでの

.config(function ($routeProvider,$locationProvider)

その後、追加し$locationProvider.hashPrefix(''); た後、

.otherwise({
        redirectTo: '/'
      });

それでおしまい。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.