Как настроить 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();
}
Это всего лишь пример улучшенной логики, конечно, каждое веб-приложение имеет разные потребности.