ハッシュ「#」なしのAngularJSルーティング


223

私はAngularJSを学習していますが、本当に私を困らせることが1つあります。

$routeProviderアプリケーションのルーティングルールを宣言するために使用します。

$routeProvider.when('/test', {
  controller: TestCtrl,
  templateUrl: 'views/test.html'
})
.otherwise({ redirectTo: '/test' });

しかし、ブラウザで自分のアプリに移動すると、app/#/testではなくが表示されapp/testます。

だから私の質問は、AngularJSがこのハッシュ#をURLに追加する理由ですか?それを回避する可能性はありますか?


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

回答:


265

実際、HTML5以外のブラウザには#(ハッシュタグ)が必要です。

それ以外の場合は、言及されたhrefのサーバーに対してHTTP呼び出しを行うだけです。#は、リクエストを発生させない古いブラウザのショートサーキットであり、多くのjsフレームワークがその上に独自のクライアントサイド再ルーティングを構築できるようにします。

使用可能な場合$locationProvider.html5Mode(true)は、角度を使用してHTML5戦略を使用するように指示できます。

HTML5戦略をサポートするブラウザのリスト:http : //caniuse.com/#feat=history


4
はい、ありがとうございます。これは私が疑ったものです。しかし、私にとってこれはかなりユーザーフレンドリーではありません!url、app / resからいくつかのリソースを利用できるようにしたいとします。私のサイトのユーザーは、代わりにapp /#/ resと入力する必要があることをどのようにして知ることができますか?
pikkvile 2013年

5
しかし、もしそうなら、なぜこれらのパスをロケーションバーに表示する必要があるのですか?ユーザーがそれらを使用しない場合は、1ページのJavaScriptアプリケーションを作成できます。
pikkvile 2013年

6
アプリケーションの状態を追跡したい場合に便利です。フレームワークは履歴メカニズムを提供します。さらに、それが直接アクセスすることができますインスタンスのURLの共有を経由して、アプリケーションの状態
plus-

6
HTML5履歴APIをサポートする最新のブラウザーでは、ハッシュタグは必要ありません。@skeepの回答と提供されているリンクを参照してください。HTML5モードでは、Angularはブラウザーがハッシュタグをサポートしていない場合にのみハッシュタグを使用します。また、不要な場合は$ routeProviderを使用する必要はありません... ng-clicksとng-includeを使用して独自のルーティングを配線できます(実際に複数のレベルが必要な場合はこれを行う必要があります) ng-viewはページごとに1回しか表示できないため、ルーティング。参照してくださいstackoverflow.com/questions/12793609/...
マーク・Rajcok

2
hashbang / pushstate /サーバー側レンダリングHTMLのケースでは、Twitterの一つが読むためにかなりいいですengineering.twitter.com/2012/12/...は、それはそれは古いブラウザで、検索との下位互換性がありますので、彼らはそれを行うために管理方法を説明しますエンジン。私はそれがangularjs固有ではないことを知っていますが、フローを再現できます。
jackdbernier 2013

47

他の人が言ったようにhtml5modeを有効に.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]

ユーザーが適切なルートを入力すると、ユーザーはアプリに誘導され、アプリはルートを読み取り、アプリ内の正しい「ページ」に移動します。

編集:ファイルやディレクトリの名前がルートと競合しないようにしてください。


これのnginxバージョンはありますか?/aboutアプリからアクセスしない限り、ページの読み込みに失敗します。
chovy

決してそれらを使用していないが、これを試してみてください。stackoverflow.com/questions/5840497/convert-htaccess-to-nginx
bearfriend

3
@chovy-ここにnGinxバージョンがあります:server {server_name my-app; root / path / to / app; 場所/ {try_files $ uri $ uri / /index.html; }}
モインハイダー2014

4
headタグの<base href = "/"> </ base>を覚えておいてください
Silvio Troia '27

ありがとう!これがなければ、ディープリンクは不可能です。ディープリンクが必要な場合、特に一部のクラウド/ Paas環境でhttpd設定に簡単にアクセスできない可能性がある場合、かわいさやURIがこれを維持するのに苦労する価値があるかどうかはまだわかりません。
Pierre Henry

39

シンプルで短く見える答えを書いてみましょう

ルーターの最後にhtml5Mode(true)を追加します。

app.config(function($routeProvider,$locationProvider) {

    $routeProvider.when('/home', {
        templateUrl:'/html/home.html'
    });

    $locationProvider.html5Mode(true);
})

HTMLヘッドにベースタグを追加

<html>
<head>
    <meta charset="utf-8">    
    <base href="/">
</head>

@plusに感謝-上記の回答の詳細


これを機能させることができませんでした。特定の詳細を含む新しい質問をstackoverflow.com/questions/36041074/…に投稿しました。これを参照してください。手助けをしていただける場合は、よろしくお願いします。
Larry Martell 2016年

30

試す

$locationProvider.html5Mode(true)

$ locationProviderの 詳細情報 $ locationの
使用


6
申し訳ありませんが、.config(function($ locationProvider){$ locationProvider.html5Mode(true)})を追加しましたが、結果はindex.html#%2Fhomeではなくindex.html / home
zloctb

12

次の情報は、https//scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtagから取得しています

きれいなURLを取得し、AngularのURLからハッシュタグを削除するのは非常に簡単です。
デフォルトでは、AngularJSはハッシュタグを使用してURLをルーティングします。例:

やらなければならないことが2つあります。

  • $ locationProviderの構成

  • 相対リンクのベースを設定する

  • $ locationサービス

Angularでは、$ locationサービスはアドレスバーのURLを解析し、アプリケーションに変更を加えます。逆も同様です。

位置情報サービスとそれが提供するものの感触を得るために、公式のAngular $ locationのドキュメントを一読することを強くお勧めします。

https://docs.angularjs.org/api/ng/service/$location

$ locationProviderおよびhtml5Mode

  • $ locationProviderモジュールを使用して、html5Modeをtrueに設定します。
  • これは、Angularアプリケーションを定義し、ルートを構成するときに行います。

    angular.module('noHash', [])
    
    .config(function($routeProvider, $locationProvider) {
    
       $routeProvider
           .when('/', {
               templateUrl : 'partials/home.html',
               controller : mainController
           })
           .when('/about', {
               templateUrl : 'partials/about.html',
               controller : mainController
           })
           .when('/contact', {
               templateUrl : 'partials/contact.html',
               controller : mainController
           });
    
       // use the HTML5 History API
       $locationProvider.html5Mode(true); });

HTML5 History APIとは何ですか?これは、スクリプトを使用してブラウザの履歴を操作するための標準化された方法です。これにより、Angularはページを更新せずにページのルーティングとURLを変更できます。この詳細については、HTML5 History APIの優れた記事をご覧ください。

http://diveintohtml5.info/history.html

相対リンクの設定

  • 相対リンクを使用してアプリケーションをリンク<base>するに<head>は、ドキュメントのにを設定する必要があります。これは、Angularアプリのルートindex.htmlファイルにある場合があります。<base>タグを見つけ、アプリに使用するルートURLに設定します。

例えば: <base href="https://stackoverflow.com/">

  • これを構成する方法は他にもたくさんあり、HTML5モードをtrueに設定すると、相対リンクが自動的に解決されます。アプリケーションのルートがURL(たとえば、/ my-base)と異なる場合は、それをベースとして使用します。

古いブラウザのフォールバック

  • $ locationサービスは、HTML5 History APIをサポートしないブラウザーのハッシュバングメソッドに自動的にフォールバックします。
  • これは透過的に行われ、機能するために何も設定する必要はありません。Angular $ location docsから、フォールバックメソッドとその仕組みを確認できます。

結論として

  • これは、AngularアプリケーションできれいなURLを取得してハッシュタグを削除する簡単な方法です。超クリーンで超高速なAngularアプリを作成して楽しんでください!

3

ApacheでAngularを提供するOS X 10.8でこれをローカルに構成したい場合は、.htaccessファイルで次の情報が役立つ場合があります。

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On
    RewriteBase /~yourusername/appname/public/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !.*\.(css|js|html|png|jpg|jpeg|gif|txt)
    RewriteRule (.*) index.html [L]
</IfModule>

オプション+ FollowSymlinksが設定されていない場合、次のようなログで禁止エラーが発生する可能性があります。

Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden

書き換えベースが必要です。それ以外の場合、リクエストはサーバールートに解決されます。サーバールートはデフォルトでローカルにプロジェクトディレクトリではありません。具体的には、vhostsを設定していない場合、リクエストがプロジェクトルートディレクトリを見つけるようにパスを設定する必要があります。たとえば、私のマシンには/ Users / me / Sitesディレクトリがあり、すべてのプロジェクトを保持しています。古いOS Xのように設定しました。

次の2行は、パスがディレクトリでもファイルでもないことを効果的に示しているため、アプリのルートパスと同じファイルやディレクトリがないことを確認する必要があります。

次の条件は、リクエストが指定されたファイル拡張子で終わっていない場合に必要なので、必要なものを追加します

そして最後の[L]はindex.htmlファイルを提供することを言っています-他のすべてのリクエストのためのあなたのアプリ。

それでも問題が解決しない場合は、Apacheログを確認してください。役立つヒントが得られます。

/private/var/log/apache2/error_log

MAMPをlocalhost apacheサーバーとして使用する場合は、最初のRewriteBaseが相対リンクであることを確認してください。例:RewriteBase / angularjs_site_folder /
デビッドダグラス

3

HTML5モードを使用するには、サーバー側でURLを書き換える必要があります。基本的に、アプリケーションのエントリポイント(index.htmlなど)へのすべてのリンクを書き換える必要があります。<base>この場合、タグを要求することも重要です。これにより、AngularJSは、アプリケーションのベースとなるURLの部分と、アプリケーションが処理する必要のあるパスを区別できるようになります。詳細については、AngularJS Developer Guide-Using $ location HTML5 mode Server Sideを参照してください。


更新

方法:html5Mode 1で動作するようにサーバーを構成する

html5Modeを有効にすると、その#文字はURLで使用されなくなります。この#記号は、サーバー側の設定を必要としないので便利です。を使用しない#場合、URLはより見栄えがよくなりますが、サーバー側の書き換えも必要になります。ここではいくつかの例を示します。

Apacheリライト

<VirtualHost *:80>
    ServerName my-app

    DocumentRoot /path/to/app

    <Directory /path/to/app>
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html to allow html5 state links
        RewriteRule ^ index.html [L]
    </Directory>
</VirtualHost>

Nginxの書き換え

server {
    server_name my-app;

    index index.html;

    root /path/to/app;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Azure IISの書き換え

<system.webServer>
  <rewrite>
    <rules> 
      <rule name="Main Rule" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="/" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

高速書き換え

var express = require('express');
var app = express();

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));

app.all('/*', function(req, res, next) {
    // Just send the index.html for other files to support HTML5Mode
    res.sendFile('index.html', { root: __dirname });
});

app.listen(3006); //the port you want to use

こちらもご覧ください


1

Angular 6では、ルーターで以下を使用できます:

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

0

以下のコードを使用して、メインページ(ホーム)にリダイレクトすることもできます。

{ path: '', redirectTo: 'home', pathMatch: 'full'}

上記のようにリダイレクトを指定した後、他のページをリダイレクトできます。次に例を示します。

{ path: 'add-new-registration', component: AddNewRegistrationComponent},
{ path: 'view-registration', component: ViewRegistrationComponent},
{ path: 'home', component: HomeComponent}

0

**

Angularのロケーション戦略としてHTML 5スタイル(PathLocationStrategy)を使用することをお勧めします

** なぜなら

  1. それは、ユーザーが理解し覚えやすい、クリーンでSEOフレンドリーなURLを生成します。
  2. クライアントに配信する前にサーバーでページを最初にレンダリングすることにより、アプリケーションのロードを高速化するサーバー側のレンダリングを利用できます。

古いブラウザーをサポートする必要がある場合にのみ、Hashlocationstrtegyを使用してください。

詳細を知るにはここをクリック

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