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


140

私が持っているAngularJSシードプロジェクトを、私は追加しました

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

app.jsファイルに追加します。IIS 7を構成してすべてのリクエストを

http://localhost/app/index.html

これでうまくいきます。どうすればよいですか?

更新:

IIS URL書き換えモジュールを見つけてダウンロードし、インストールしたところです。これにより、目標を簡単かつ明確に達成できると期待しています。

アップデート2

これは私が達成しようとしていることを要約していると思います(AngularJS開発者のドキュメントから取得):

このモードを使用するには、サーバー側で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書き換えモジュールで2つの受信ルールを定義しています。最初のルールは:

IIS URL書き換え受信規則1

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

IIS URL書き換え受信規則2

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


これをありがとう!非常に役立ちます!
Ash Clarke

2番目のルールは非常に重要です。AngularJSを提供するページに明示的にトリガーするのapp/index.htmlはなく app/、ルーティングすることを確認する必要があります。私はそれを理解する前に私の人生の2時間を失いました。:-)
デクスターレガスピ2014年

ASP.NET MVCを使用してRouteConfig.csに追加する別の方法:routes.MapRoute(name: "Default"、url: "{* anything}"、defaults:new {controller = "Home"、action = "Index"、 }); そして、HomeController IndexはFile( "〜/ index-anyhinghere.html"、 "text / html");を返します。その後、アプリはIISに依存しなくなります
ツールキット

「 『Webインストーラ』からURL書き換えモジュール」をインストールしました。URL書き換えモジュールがそこにない場合、リロード中に、書き換えは機能しません。INSTALL URL書き換えモジュール。:)
Bimal Das

回答:


289

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

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

  <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を使用している場合、APIがwww.yourdomain.com/api3番目の入力(条件の3行目)のために動作している場合、これは機能します。


2
これは非常に便利で、最も完全であることがわかりました。ありがとう!
マリオ

2
@Marioを助けてくれてうれしい
Yagiz Ozturk

5
パーフェクト!これは私にとって難しい問題でした。これに何時間も費やしました。ありがとう!他の人へのアドバイス:<action type = "Rewrite" url "/index.html" />にindex.htmlを追加してから、index.html(Angular SPAのルートディレクトリファイル、<base href = "/ index .html "/>上記のコードを処理すると、<base href />と一致しなかったため、正しく機能しませんでした。「/(api)」パターンの巨大な小道具も、その部分でつまずき続けました。
Brad Martin

Azure Webサイトでホストしている場合はどうなりますか?
ツールキット、

7
Angularルーティングのためにこれらのフープを飛び越えなければならないのは冗談です。これは私にとって角度のあるルーティングを殺します。なんてめちゃくちゃ。
user441521

38

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

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

これは、localhostに複数のアプリケーションがあるため、他のパーシャルへのリクエストがlocalhost/app/view1代わりに行われていたためですlocalhost/myApplication/app/view1

うまくいけば、これは誰かを助けるでしょう!


1
これは必要ありませんでしたが、質問の編集は素晴らしかったです。ありがとう!
アッシュクラーク

2
これも役立ちます。ページをリロードするときに私のために働いた。すべてのファイルに特別なルールがない場合:coderwall.com/p/mycbiq
G

@ ash-clarkeが言ったように、それは必要ではありませんが、ページ上のリンクがそれがどの「サブディレクトリ」に属しているかを認識できないようにするので、とにかく良い習慣です。
デクスターLegaspi 2014年

@PerG私は上記の解決策に遭遇しましたが、リロードではありませんでした、これが私のコードです:stackoverflow.com/questions/25644287/iis-url-rewrite-rules 任意のアイデア?
amcdnl 2014

わからない、または特定の通話をtiフィルターで除外しようとした 回避策は、他のドメインなどでAPIを使用することです。しかし、おそらくこれはuのソリューションではありません。しかし、あなたは上記の私のリンクで尋ね続けることができます。そして多分著者はあなたに答えることができますか?
G

11

私の場合、正しい書き換えルールを設定した後、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>

10

次の2つの条件のみの問題:

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

ディスク上に物理的に存在する場合にのみ機能するということです{REQUEST_FILENAME} です。これは、誤って名前が付けられた部分ビューのリクエストが404の代わりにルートページを返すシナリオが存在する可能性があることを意味します。

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

  <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>

1
これらすべてが適切に配置されていれば、サイトは正常に読み込まれますが、ルートに沿ったパスにいると問題が発生します。したがって、ブラウザのパスが10.34.34.46/jbvdev/documents/BC498484の場合、 最初は 正常に表示されますが、リフレッシュを押すと、10.34.34.46 / jbvdev / documentsで cssとjsを探し始めるため、すべてが壊れます。 / cssまたは10.34.34.46/jbvdev/documents/js これを解決する方法を知っている人はいますか?
Michael Mahony、2016年

1

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

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

index.html

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

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

web.config

最初に404をカスタムページにリダイレクトします(例: "Home / Error")。

<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​​を通常どおりトリガーさせるために、いくつかの改善されたロジックでエラー関数を強化することができます(推奨?)。これらの角のあるルートがあるとしましょう

.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

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


1

AngularとIISで同様の問題があり、手動更新で404ステータスコードをスローし、最も投票されたソリューションを試しましたが、それは私にとってはうまくいきませんでした。また、WebDAVとハンドラーの変更を処理する必要がある他の多くのソリューションを試しましたが、どれも機能しませんでした。

幸いなことに、私はこの解決策を見つけ、それが機能しました(不要な部分を取り除いた)。上記のいずれもうまくいかない場合、またはそれらを試す前にさえ、これを試して、それがiisの問題で角度のある展開を修正するかどうか確認してください。

サイトのルートディレクトリのwebconfigにスニペットを追加します。私の理解では、404ステータスコードを継承(applicationhost.config、machine.config)から削除してから、サイトレベルで404ステータスコードを作成し、カスタム404ページとしてホームページにリダイレクトします。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom">
      <remove statusCode="404"/>
      <error statusCode="404" path="/index.html" responseMode="ExecuteURL"/>
    </httpErrors>
  </system.webServer>
</configuration>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.