web-dev-qa-db-ja.com

AngularJS HTML5モード-サーバー固有の変更なしで直接リンクはどのように機能しますか?

注:この質問は次のようにも読める:

Javaでハッシュバンレスクライアント側mvcフレームワークのブックマークをサポートする方法。

hashtagsを使用するangularアプリをhtml5mode。設定しました

$locationProvider.html5Mode(true);

また、ランディングページ(index.html)からのすべてのリンクは正常に機能します。

問題は、部分的なURLが直接参照される場合、サーバーエンドポイントの定義がクライアント側で定義されたルートに結合されないため、当然404を取得します。

したがって、HTML5を使用しないと、SEOに対応しないハッシュバングが得られますが、ランディングページ(アンギュラーをブートストラップするページ)以外をブックマークすることはできません。

デフォルトのランディングページ(index.html)を最初にリクエストした場合、つまりhtpp://mydomain.com/が機能する理由:

  1. ブラウザーはサーバーからindex.htmlを要求します
  2. サーバーはindex.htmlを返し、ブラウザはangular frameworkをロードします
  3. URLの変更はクライアント側のルーターに送信され、適切なパーシャルがロードされます。

(ie) http://mydomain.com/foo がブラウザから直接要求された場合、なぜ機能しないのか:

  1. ブラウザーはサーバーにmydomain/fooを要求します。
  2. リソースが存在しません
  3. サーバーが404を返す

この話から何かが欠けている、私はちょうど何がわからない。ここに私が見ることができる唯一の2つの答えがあります...

  • これは仕様によるものです。これはどのように動作するはずですか?ユーザーは常にクライアントMVCフレームワークのbootstrapページ(通常はindex.html)に移動し、そこから移動する必要があります。これは、状態を保存できず、ブックマークする方法がないため理想的ではありません。 ...クロールは言うまでもありません。
  • サーバーソリューション。これはサーバーサイドのトリックで回避できますか?たとえば、すべてのリクエストでindex.htmlを返し、すぐに追加のコンテキストでルーターを呼び出します。もしそうなら、これはAngularJSが完全にクライアント側であり、ハッキングのように見えるという目的に反しています。
45

AngularJSドキュメント は実際にこれに言及しています

サーバー側このモードを使用するには、サーバー側でURLを書き換える必要があります。基本的には、アプリケーションのエントリポイント(index.htmlなど)へのすべてのリンクを書き換える必要があります。

この場合、Javaベースのソリューションの1つは、サーバーに「すべてのURLをindex.htmlにマップする」ことです。これは、任意のHTTPサーバーまたはコンテナーで実行できます。アプリケーションをHTTPサーバーに依存しない(つまり、Apache対NginX、またはTomcat/JBossのみ)ために、Java/Servetを使用してこれを実装しました。

Web.xmlで:

  <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
      <servlet-name>StaticServlet</servlet-name>
      <jsp-file>/index.jsp</jsp-file>
  </servlet>

  <servlet-mapping>
      <servlet-name>StaticServlet</servlet-name>
      <url-pattern>/app</url-pattern>
  </servlet-mapping>

そして、index.jspは単純に次のようになります。

<%@ include file="index.html" %>

そして、index.html内のタグに次を追加します。

<base href="/app" />
39

私はPHPサイト。このサーバーサイドコードをすべて/ apiから外します。これをAngularから分離するためのルートです。Apacheの設定を更新することで私が思いついた解決策は次のとおりです。

RewriteEngine on
#let the php framework do its thing
RewriteRule ^(api/.*)$ index.php?url=$1 [QSA,L,NC]
#let angular do its thing
RewriteCond %{REQUEST_FILENAME} !-f      
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.html [NC,L]

Flight PHPフレームワーク http://www.awnage.com/2013/10/10/taking-flight- with-angularjs /

3
Awnage