Як налаштувати IIS для переписування URL-адреси програми AngularJS в режимі HTML5?


140

У мене є проект насіння AngularJS і я додав

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

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

http://localhost/app/index.html

так що це працює для мене. Як це зробити?

Оновлення:

Щойно я виявив, завантажив і встановив модуль перезапису URL-адреси IIS , сподіваючись, що це дозволить легко та очевидно досягти своєї мети.

Оновлення 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 Перезапис вхідного правила 1

Друге правило:

IIS Перезапис вхідного правила 2

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


Дякую за це! Дуже корисний!
Еш Кларк

друге правило є критичним: вам потрібно переконатися, що він спрямований, app/index.htmlа не app/ явно запускати сторінку, яка обслуговує AngularJS. Я втратив 2 години свого життя, перш ніж я зрозумів це. :-)
Декстер Легаспі

Інший спосіб використання ASP.NET MVC та додавання до RouteConfig.cs: route.MapRoute (ім'я: "За замовчуванням", URL: "{* що-небудь}", за замовчуванням: new {controller = "Home", action = "Index", }); і ваш індекс HomeController просто повертає файл ("~ / index-anyhinghere.html", "text / html"); Тоді ваша програма стає незалежною від IIS
інструментарій

Мені довелося встановити "Модуль перезапису URL-адреси з" Веб-інсталятора "". Якщо модуля перезапису URL-адреси немає, то під час перезавантаження перезапис не працюватиме. ВСТАНОВИТИ модуль перезапису URL-адреси. :)
Bimal Das

Відповіді:


289

Я виписую правило в 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 Rewrite URL-адреси на сервер.

Також якщо ви використовуєте Web API та IIS, це працюватиме, якщо ваш API працює www.yourdomain.com/apiчерез третій вхід (третій рядок умови).


2
Це було дуже корисно, і я вважав, що це найповніше. Дякую!
Маріо

2
рада, що це допомагає @Mario
Yagiz Ozturk

5
ЗДОРОВИЙ! Ця проблема була для мене важкою проблемою, витративши години на роботу. Дякую! Порада для будь-якого іншого: я додав index.html до <action type = "Переписати" url "/index.html" /> Потім у мій index.html (файл кореневого каталогу для Angular SPA, <base href = "/ index .html "/> Коли я скопіював код вище, він не відповідав моєму <базовому href />, тому він не працював правильно. Величезні реквізити для шаблону" / (api) "також я продовжував спотикатися на цій частині.
Бред Мартін

що робити, якщо я розміщую веб-сайти Azure?
Інструментарій

7
Жарт, що для кутової маршрутизації нам доведеться стрибати через ці обручі. Це вбиває кутову маршрутизацію для мене. Який безлад.
користувач441521

38

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

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

Це тому, що у мене є декілька заявок у localhost, тому запити до інших партій бралися localhost/app/view1замість нихlocalhost/myApplication/app/view1

Сподіваємось, це комусь допомагає!


1
Мені це не потрібно було, але зміни питань були чудовими. Дякую!
Еш Кларк

2
Також це може бути корисно. Працював для мене під час перезавантаження сторінки. Без особливих правил для кожного файлу: coderwall.com/p/mycbiq
Per G

як сказав @ ash-clarke, це не обов'язково, але все-таки це добра практика, оскільки дозволяє посилання на сторінці бути агностичними щодо того, до якого «підкаталогу» він належить.
Декстер Легаспі

@PerG Я наткнувся на вищезазначене рішення, працюючи, але не перезавантажуючись, ось мій код: stackoverflow.com/questions/25644287/iis-url-rewrite-rules Будь-які ідеї?
amcdnl

Я не знаю чи не намагався ти відфільтрувати певні дзвінки. Шлях у тому, щоб мати API на іншому домені тощо. Але, можливо, це не рішення для u. Але ви можете продовжувати запитувати в моєму посиланні вище. А може автор може відповісти вам?
Пер G

11

У моєму випадку я продовжував отримувати 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>

10

Проблема лише з цими двома умовами:

  <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 Спочатку він відображається нормально, але якщо я натисніть оновлення, все порушується, оскільки він починає шукати css та js у 10.34.34.46/jbvdev/documents / css або 10.34.34.46/jbvdev/documents/js Хтось знає, як це вирішити?
Майкл Махоні

1

Найпростіший спосіб, який я знайшов, - це просто перенаправити запити, які викликають 404 клієнту. Це робиться, додаючи хештег навіть тоді, коли $locationProvider.html5Mode(true)встановлено.

Цей трюк працює для середовищ із більшою кількістю веб-додатків на одному веб-сайті та вимагає обмежень цілісності URL-адреси (зовнішня аутентифікація EG). Ось крок за кроком, як це зробити

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 спрацьовує нормально, коли на клієнті нічого не знайдеться. Скажімо, у вас є ці кутові маршрути

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

Є сенс перенаправляти 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();
}

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


1

Я намагався розгорнути простий додаток Angular 7 в веб-додаток Azure. Все працювало чудово, до тих пір, поки ви не оновили сторінку. Роблячи це, подав мені вміст, переміщений у 500 помилок. Я читав як у кутових документах, так і на декількох форумах, що мені потрібно додати файл web.config до мого розгорнутого рішення та переконайтесь, що перезапис правила перезапис у файл index.html. Після декількох годин розчарувань і проб і помилок я виявив, що помилка була досить простою: додавання тегу навколо розмітки мого файлу.


1

У мене була аналогічна проблема, коли Angular та IIS кидали код статусу 404 під час ручного оновлення та намагалися вирішити найбільш голосові рішення, але це не спрацювало для мене. Також спробував купу інших рішень, пов’язаних із WebDAV та зміною обробників, і жодне не спрацювало.

На щастя, я знайшов це рішення, і воно спрацювало (вийняло непотрібні мені частини). Тож якщо жодне з перерахованих вище не працює для вас або навіть перед тим, як спробувати їх, спробуйте це, і подивіться, чи це фіксує ваше кутове розгортання у проблемі iis.

Додайте фрагмент до веб-конфігу в кореневому каталозі вашого сайту. З мого розуміння, він видаляє код статусу 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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.