Как настроить IIS для перезаписи URL-адреса приложения AngularJS в режиме HTML5?

у меня есть проект семян AngularJS и я добавил

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

приложение.файл js. Я хочу настроить IIS 7 для маршрутизации всех запросов в

http://localhost/app/index.html

Так что это работает для меня. Как мне это сделать?

обновление:

Я только что обнаружил, скачал и установил модуль перезаписи URL IIS, надеясь, что это сделает его легким и очевидным, чтобы достичь своей цель.

обновление 2:

Я думаю, это подводит итог тому, что я пытаюсь достичь (взято из документация для разработчиков AngularJS):

использование этого режима требует перезаписи URL на стороне сервера, в основном вам нужно переписать все ваши ссылки на точку входа вашего применение (например, индекс.html)

обновление 3:

Я все еще работаю над этим и я понимаю, что мне не нужно перенаправление (есть правила, которые переписывают) определенные URL-адреса, такие как

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

поэтому все, что находится в каталогах css, js, lib или partials, не перенаправляется. Все остальное нужно будет перенаправить на app / index.HTML-код

кто-нибудь знает, как достичь этого легко, не добавляя правило для каждого файла?

обновление 4:

у меня есть 2 входящих правила, определенные в модуле перезаписи URL IIS. Первое правило есть:

IIS URL Rewrite Inbound Rule 1

второе правило:

IIS URL Rewrite Inbound Rule 2

Теперь, когда я перехожу к localhost / app/view1, он загружает страницу, однако вспомогательные файлы (те, которые находятся в каталогах css, js, lib и partials) также переписываются в приложение / индекс.html-страница-так что все возвращается как индекс.html-страница независимо от того, какой URL используется. Я предполагаю, что это означает мое первое правило, которое должно предотвратить обработку этих URL-адресов второе правило, не работает.. есть идеи? ...кто? ...Я чувствую себя таким одиноким... :-(

5 ответов


Я пишу правило в интернете.config после $locationProvider.html5Mode(true) находится в 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>

в мой индекс.html я добавил Это в <head>

<base href="/">

не забудьте установить IIS URL переписать на сервере.

также, если вы используете веб-API и IIS, это будет работать, если ваш API находится в www.yourdomain.com/api из-за третьего входа (третья строка условия).


входящие правила IIS, как показано в вопросе, работают. Мне пришлось очистить кэш браузера и добавить следующую строку в верхней части моего <head> раздел индекса.html страница:

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

это потому что у меня есть более одного приложения в localhost и поэтому просит других фрагментов принимаются к localhost/app/view1 вместо localhost/myApplication/app/view1

надеюсь, это поможет кто-то!


в моем случае я продолжал получать 403.14 после того, как я установил правильные правила перезаписи. Оказывается, у меня был каталог с тем же именем, что и один из моих URL-маршрутов. Как только я удалил правило перезаписи 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>

проблема только с этими двумя условиями:

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

это то, что они работают только до тех пор, пока {REQUEST_FILENAME} существует физически на диске. Это означает, что могут быть сценарии, в которых запрос на неправильно названное частичное представление вернет корневую страницу вместо 404, что приведет к загрузке angular дважды (и в некоторых сценариях это может привести к неприятному бесконечному циклу).

таким образом, некоторые безопасные" резервные " правила были бы рекомендованы избегайте этих трудных для устранения неполадок:

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

самый простой способ, который я нашел, - просто перенаправить запросы, которые запускают 404 клиенту. Это делается путем добавления хэштега, даже если $locationProvider.html5Mode(true) установлен.

этот трюк работает для сред с большим количеством веб-приложений на том же веб-сайте и требует ограничений целостности URL (например, внешняя аутентификация). Вот шаг за шагом, как это сделать

.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);
}

это самый простой способ.


это возможно (целесообразно?) для улучшения функции ошибки с некоторой улучшенной логикой перенаправить 404 клиенту только тогда, когда url действителен, и пусть триггер 404 обычно, когда ничего не будет найдено на клиенте. Допустим, у вас есть эти угловые маршруты

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

имеет смысл перенаправлять URL-адрес клиенту только тогда, когда он начинается с "/New" или "/Show/"

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();
}

это просто пример улучшенной логики, конечно, каждое веб-приложение имеет разные потребности