Hoe configureer ik IIS voor het herschrijven van URL’s van een AngularJS-toepassing in HTML5-modus?

Ik heb het AngularJS seed-projecten ik heb

toegevoegd

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

naar het app.js-bestand. Ik wil IIS 7 configureren om alle verzoeken te routeren naar

http://localhost/app/index.html

zodat dit voor mij werkt. Hoe doe ik dit?

Bijwerken:

Ik heb zojuist de IIS URL Rewrite-moduleontdekt, gedownload en geïnstalleerd , in de hoop dat dit het gemakkelijk en duidelijk maakt om mijn doel te bereiken.

Update 2:

Ik denk dat dit samenvat wat ik probeer te bereiken (overgenomen uit de AngularJS Ontwikkelaarsdocumentatie):

Het gebruik van deze modus vereist herschrijven van URL’s aan serverzijde,
eigenlijk moet je al je links naar het toegangspunt van je . herschrijven
applicatie (bijv. index.html)

Update 3:

Ik ben hier nog steeds mee bezig en ik realiseer me dat ik bepaalde URL’s zoals

NIET hoef om te leiden (regels te hebben die herschrijven)

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

dus alles wat zich in de css-, js-, lib- of partiële mappen bevindt, wordt niet omgeleid. Al het andere moet worden omgeleid naar app/index.html

Iedereen weet hoe je dit gemakkelijk kunt bereiken zonder een regel toe te voegen voor elk afzonderlijk bestand?

Update 4:

Ik heb 2 inkomende regels gedefinieerd in de IIS URL Rewrite-module. De eerste regel is:

De tweede regel is:

Als ik nu naar localhost/app/view1 navigeer, wordt de pagina geladen, maar de ondersteunende bestanden (die in de mappen css, js, lib en gedeeltelijke bestanden) worden ook herschreven naar de app/index.html-pagina – dus alles komt terug als de index.html-pagina, ongeacht welke URL wordt gebruikt. Ik denk dat dit betekent dat mijn eerste regel, die moet voorkomen dat deze URL’s worden verwerkt door de tweede regel, niet werkt.. enig idee? …iedereen? …Ik voel me zo alleen… 🙁


Antwoord 1, autoriteit 100%

Ik schrijf een regel in web.config nadat $locationProvider.html5Mode(true)is ingesteld in app.js.

Hoop, helpt iemand.

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

In mijn index.html heb ik dit toegevoegd aan <head>

<base href="/">

Vergeet niet om IIS URL Rewriteop de server te installeren.

Ook als je Web API en IIS gebruikt, werkt dit als je API op www.yourdomain.com/apistaat vanwege de derde invoer (derde regel van voorwaarde).


Antwoord 2, autoriteit 13%

De IIS-inkomende regels zoals getoond in de vraag werken. Ik moest de browsercache wissen en de volgende regel toevoegen in de top van mijn <head>sectie van de index.html pagina:

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

Dit komt omdat ik meer dan één applicatie in LocalHost heb en dus verzoeken aan andere gedeeltelijke deelnemers werden gebracht naar localhost/app/view1in plaats van localhost/myApplication/app/view1

Hopelijk helpt dit iemand!


Antwoord 3, Autoriteit 4%

Het probleem met alleen deze twee voorwaarden:

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

Is dat ze alleen werken zolang de {REQUEST_FILENAME}bestaat fysiek op schijf . Dit betekent dat er scenario’s kunnen zijn waar een verzoek om een ​​onjuist genoemde gedeeltelijke weergave de hoofdpagina zou retourneren in plaats van een 404 die enorm zou kunnen worden geladen (en in bepaalde scenario’s kan het een smerige oneindige lus veroorzaken).

Dus, sommige veilige “fallback” -regels zouden worden aanbevolen om deze moeilijk te voorkomen om problemen op te lossen:

 <add input="{REQUEST_FILENAME}" pattern="(.*?)\.html$" negate="true" />
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.js$" negate="true" />
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.css$" negate="true" />

of een voorwaarde die overeenkomt met elk bestand dat eindigt :

<conditions>
  <!-- ... -->
  <add input="{REQUEST_FILENAME}" pattern=".*\.[\d\w]+$" negate="true" />
</conditions>

Antwoord 4, Autoriteit 4%

In mijn geval bleef ik een 403.14 ontvangen nadat ik de juiste herschrijfregels had ingesteld. Het blijkt dat ik een map had die dezelfde naam had als een van mijn URL-routes. Zodra ik de ISDirectory Rewrite-regel heb verwijderd, werkten mijn routes correct. Is er een geval waar het verwijderen van de directory-negatie problemen kan veroorzaken? Ik kan in mijn geval geen bedenken. Het enige geval dat ik kan bedenken is als u door een map met uw app kunt bladeren.

<rule name="fixhtml5mode" stopProcessing="true">
  <match url=".*"/>
  <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  </conditions>
  <action type="Rewrite" url="/" />
</rule>

Antwoord 5

Ik had een soortgelijk probleem met hoekige en IIS gooien een 404-statuscode op handgeschakeld en probeerde de meest gestemde oplossing, maar dat werkte niet voor mij. Probeerde ook een stel andere oplossingen om te gaan met WebDAV en veranderende handlers en geen gewerkt.

Gelukkig heb ik deze oplossing en het werkte ( haalde onderdelen die ik niet nodig had). Dus als geen van de bovenstaande voor u werkt of zelfs alvorens ze probeert, probeert u dit en kijk of dat uw hoekige implementatie op IIS-probleem oplost.

Voeg het snippet toe aan uw webconfig in de hoofdmap van uw site. Uit mijn begrip verwijdert het de 404-statuscode van elke erfenis (applicationhost.config, machine.config), creëert vervolgens een 404-statuscode op het niveau van de site en leidt terug naar de startpagina als een aangepaste 404-pagina.

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

Antwoord 6

De gemakkelijkste manier die ik heb gevonden, is om de verzoeken die 404 activeren door te sturen naar de client. Dit wordt gedaan door een hashtag toe te voegen, zelfs als $locationProvider.html5Mode(true)is ingesteld.

Deze truc werkt voor omgevingen met meer webapplicaties op dezelfde website en die URL-integriteitsbeperkingen vereisen (bijv. externe authenticatie). Hier is stap voor stap hoe u dit moet doen

index.html

Stel het <base>element correct in

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

web.config

Eerste 404 omleiden naar een aangepaste pagina, bijvoorbeeld “Home/Error”

<system.web>
    <customErrors mode="On">
        <error statusCode="404" redirect="~/Home/Error" />
    </customErrors>
</system.web>

Thuiscontroller

Implementeer een eenvoudig ActionResultom invoer te “vertalen” in een route aan de clientzijde.

public ActionResult Error(string aspxerrorpath) {
    return this.Redirect("~/#/" + aspxerrorpath);
}

Dit is de eenvoudigste manier.


Het is mogelijk (aan te raden?) om de Error-functie te verbeteren met wat verbeterde logica om 404 alleen naar de client om te leiden als de URL geldig is en de 404 normaal te laten triggeren als er niets op de client wordt gevonden.
Laten we zeggen dat je deze hoekige routes hebt

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

Het is logisch om de URL alleen naar de client om te leiden als deze begint met “/New” of “/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();
}

Dit is slechts een voorbeeld van verbeterde logica, natuurlijk heeft elke webtoepassing andere behoeften


Antwoord 7

Ik heb geprobeerd een eenvoudige Angular 7-toepassing te implementeren in een Azure Web App.
Alles werkte prima, tot het punt waarop je de pagina ververst. Door dit te doen, kreeg ik een 500-fout – verplaatste inhoud.
Ik heb zowel in de Angular-documenten als in een paar goede forums gelezen dat ik een web.config-bestand moet toevoegen aan mijn geïmplementeerde oplossing en ervoor moet zorgen dat de herschrijfregel terugvalt op het index.html-bestand.
Na uren van frustratie en testen met vallen en opstaan, ontdekte ik dat de fout vrij eenvoudig was: een tag toevoegen rond mijn bestandsopmaak.


Antwoord 8

De beste oplossing hiervoor werkte helaas niet voor mij met .NET Framework 4.5 en IIS 6.2. Ik heb het werkend gekregen door eerst alle stappen te volgen om de URL Rewrite toolvan Microsoft en pas vervolgens mijn Web.config-bestand aan om het volgende op te nemen:

   <system.webServer>
    <!-- handlers etc -->
    <rewrite>
      <rules>
        <rule name="Angular Routes" stopProcessing="true">
          <match url="(^(?!.*\.[\d\w]+$).*)" />
          <conditions logicalGrouping="MatchAny">
            <add input="{REQUEST_URI}" pattern=".*\/api\/.*" negate="true" />
          </conditions>
          <action type="Rewrite" url="./index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

De eerste reguliere expressie gebruikt negatieve look-aheads om NIET overeen te komen met een bestandsextensie aan het einde van de URI. Vervolgens wordt binnen de voorwaarde elke URI inclusief /api/ook genegeerd.

Met deze configuratie kan ik de Angular-app vernieuwen zonder de routering te verbreken en ook toegang krijgen tot mijn API zonder opnieuw te worden geschreven.

Other episodes