web-dev-qa-db-ja.com

HTML5モードでAngularJSアプリケーションを書き換えるURLに対してIISを構成するにはどうすればよいですか?

AngularJSシードプロジェクト があり、追加しました

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

app.jsファイルに。すべての要求をルーティングするようにIIS 7を構成したい

http://localhost/app/index.html

これが私のために働くように。どうすればいいですか?

更新:

IIS URL Rewrite module を発見、ダウンロード、インストールしたばかりです。これにより、私の目標を簡単かつ明確に達成できることを期待しています。

更新2

これは私が達成しようとしていることを要約していると思います( AngularJS Developer documentation から取られました):

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

更新3:

私はまだこれに取り組んでおり、次のような特定のURLをリダイレクトする(書き換えるルールを持たない)必要はない

http://localhost/app/lib/angular/angular.js
http://localhost/app/partials/partial1.html

そのため、css、js、lib、partialsディレクトリにあるものはリダイレクトされません。その他はすべてapp/index.htmlにリダイレクトする必要があります

すべてのファイルにルールを追加することなく、これを簡単に達成する方法を知っている人はいますか?

更新4:

IIS URL Rewriteモジュールで定義された2つの受信ルールがあります。最初のルールは次のとおりです。

IIS URL Rewrite Inbound Rule 1

2番目のルールは次のとおりです。

IIS URL Rewrite Inbound Rule 2

Localhost/app/view1に移動すると、ページが読み込まれますが、サポートファイル(css、js、lib、partialsディレクトリ内のファイル)もapp/index.htmlページに書き換えられます。どのURLが使用されていてもindex.htmlページに戻ります。これは、これらのURLが2番目のルールによって処理されるのを防ぐはずの最初のルールが機能していないことを意味すると思います。 ...誰でも? ...私は孤独を感じる... :-(

133
Dean

質問DOに示されているIISインバウンドルールは機能します。ブラウザのキャッシュをクリアし、index.htmlページの<head>セクションの先頭に次の行を追加する必要がありました。

<base href="/myApplication/app/" />

これは、localhostに複数のアプリケーションがあるため、他のパーシャルへのリクエストがlocalhost/app/view1ではなくlocalhost/myApplication/app/view1に送られたためです。

これが誰かの助けになることを願っています!

36
Dean

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

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

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS Routes" 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 Rewrite をインストールすることを忘れないでください。

また、Web APIとIISを使用している場合、3番目の入力(条件の3行目)のためにAPIがwww.yourdomain.com/apiにある場合、これは機能します。

267
Yagiz Ozturk

私の場合、正しい書き換えルールを設定した後、403.14を取得し続けました。 URLルートの1つと同じ名前のディレクトリがあったことがわかりました。 IsDirectory書き換えルールを削除すると、ルートは正しく機能しました。ディレクトリ否定を削除すると問題が発生する場合がありますか?私の場合は何も考えられません。私が考えることができる唯一のケースは、アプリでディレクトリを閲覧できるかどうかです。

<rule name="fixhtml5mode" stopProcessing="true">
  <match url=".*"/>
  <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  </conditions>
  <action type="Rewrite" url="/" />
</rule>
9
Josh C

これらの2つの条件のみを持つ問題:

  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />

{REQUEST_FILENAME}ディスク上に物理的に存在する である場合にのみ機能するということです。これは、誤って名前が付けられた部分ビューのリクエストが404ではなくルートページを返し、angularが2回ロードされるシナリオがあることを意味します(特定のシナリオでは、厄介な無限を引き起こす可能性がありますループ)。

したがって、トラブルシューティングが困難なこれらの問題を回避するために、いくつかの安全な「フォールバック」ルールが推奨されます。

  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.html$" negate="true" />
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.js$" negate="true" />
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.css$" negate="true" />

または ファイルの末尾に一致 の条件:

<conditions>
  <!-- ... -->
  <add input="{REQUEST_FILENAME}" pattern=".*\.[\d\w]+$" negate="true" />
</conditions>
9

私が見つけた最も簡単な方法は、404をトリガーするリクエストをクライアントにリダイレクトすることです。これは、$locationProvider.html5Mode(true)が設定されている場合でもハッシュタグを追加することで実行されます。

このトリックは、同じWebサイト上により多くのWebアプリケーションがあり、URL整合性の制約(外部認証など)を必要とする環境で機能します。手順を追って説明します

index.html

<base>要素を適切に設定します

<base href="@(Request.ApplicationPath + "/")">

web.config

最初に404をカスタムページにリダイレクトします(例:「ホーム/エラー」)

<system.web>
    <customErrors mode="On">
        <error statusCode="404" redirect="~/Home/Error" />
    </customErrors>
</system.web>

ホームコントローラー

単純なActionResultを実装して、クライアント側ルートで入力を「翻訳」します。

public ActionResult Error(string aspxerrorpath) {
    return this.Redirect("~/#/" + aspxerrorpath);
}

これが最も簡単な方法です。


URLが有効な場合にのみ404をクライアントにリダイレクトし、クライアントで何も見つからない場合に404​​を正常にトリガーできるようにするいくつかの改良されたロジックでエラー機能を強化することが可能です。これらのangularルートがあるとします

.when("/", {
    templateUrl: "Base/Home",
    controller: "controllerHome"
})
.when("/New", {
    templateUrl: "Base/New",
    controller: "controllerNew"
})
.when("/Show/:title", {
    templateUrl: "Base/Show",
    controller: "controllerShow"
})

「/ New」または「/ Show /」で始まる場合にのみクライアントにURLをリダイレクトするのは理にかなっています

public ActionResult Error(string aspxerrorpath) {
    // get clientside route path
    string clientPath = aspxerrorpath.Substring(Request.ApplicationPath.Length);

    // create a set of valid clientside path
    string[] validPaths = { "/New", "/Show/" };

    // check if clientPath is valid and redirect properly
    foreach (string validPath in validPaths) {
        if (clientPath.StartsWith(validPath)) {
            return this.Redirect("~/#/" + clientPath);
        }
    }

    return new HttpNotFoundResult();
}

これは改善されたロジックの単なる例であり、もちろんすべてのWebアプリケーションには異なるニーズがあります

1
Naigel

単純なAngular 7アプリケーションをAzure Webアプリにデプロイしようとしています。ページを更新するまで、すべて正常に機能しました。そうすると、500エラー-移動されたコンテンツが表示されました。 Angular docsといくつかのフォーラムの両方で、展開したソリューションにweb.configファイルを追加し、index.htmlファイルへの書き換えルールのフォールバックを確認する必要があることを読みました。 。数時間のフラストレーションと試行錯誤のテストの後、ファイルマークアップの周りにタグを追加するという非常に簡単なエラーが見つかりました。

0
Kelson Martins