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

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

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

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

http://localhost/app/index.html

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

Update:

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

Обновление 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:

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

IIS URL Rewrite Inbound Rule 1

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

IIS URL Rewrite Inbound Rule 2

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

Ответ 1

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

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

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

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

Ответ 2

Я выписываю правило в web.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>

В моем index.html я добавил это в <head>

<base href="/">

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

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

Ответ 3

В моем случае я продолжал получать 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>

Ответ 4

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

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

Ответ 5

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

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

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

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


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

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

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