it-swarm.com.de

Wie konfiguriere ich IIS für das URL-Umschreiben einer AngularJS-Anwendung im HTML5-Modus?

Ich habe das AngularJS-Seed-Projekt und ich habe hinzugefügt

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

in die Datei app.js. Ich möchte IIS 7 so konfigurieren, dass alle Anforderungen an weitergeleitet werden

http://localhost/app/index.html

damit das bei mir funktioniert. Wie mache ich das?

Update:

Ich habe gerade das IIS URL Rewrite-Modul entdeckt, heruntergeladen und installiert , in der Hoffnung, dass dies das Erreichen meines Ziels einfach und offensichtlich macht.

Update 2 :

Ich denke, dies fasst zusammen, was ich erreichen möchte (aus der AngularJS Developer-Dokumentation ):

Bei Verwendung dieses Modus muss die URL auf der Serverseite neu geschrieben werden. Grundsätzlich müssen Sie alle Ihre Links zum Einstiegspunkt Ihrer Anwendung (z. B. index.html) neu schreiben.

Update 3:

Ich arbeite immer noch daran und mir ist klar, dass ich bestimmte URLs NICHT umleiten (Regeln haben, die sie umschreiben) muss, wie z

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

alles, was sich in den Verzeichnissen css, js, lib oder partials befindet, wird nicht umgeleitet. Alles andere muss nach app/index.html umgeleitet werden

Weiß jemand, wie dies einfach zu erreichen ist, ohne für jede einzelne Datei eine Regel hinzufügen zu müssen?

Update 4:

Ich habe 2 Regeln für eingehende Nachrichten, die im URL-Rewrite-Modul IIS definiert sind. Die erste Regel lautet:

IIS URL Rewrite Inbound Rule 1

Die zweite Regel lautet:

IIS URL Rewrite Inbound Rule 2

Wenn ich jetzt zu localhost/app/view1 navigiere, wird die Seite geladen, aber die unterstützenden Dateien (die in den Verzeichnissen css, js, lib und partials) werden ebenfalls auf die Seite app/index.html geschrieben - also kommt alles Zurück als index.html Seite, egal welche URL verwendet wird. Ich denke, das bedeutet, dass meine erste Regel, die verhindern soll, dass diese URLs von der zweiten Regel verarbeitet werden, nicht funktioniert. Irgendwelche Ideen? ...jemand? ... ich fühle mich so alleine ... :-(

129
Dean

Die eingehenden Regeln IIS, wie in der Frage DO gezeigt, funktionieren. Ich musste den Browser-Cache leeren und die folgende Zeile oben in meinem Abschnitt <head> der Seite index.html hinzufügen:

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

Dies liegt daran, dass ich mehr als eine Anwendung in localhost habe und daher Anfragen an andere Partials an localhost/app/view1 statt localhost/myApplication/app/view1 gesendet wurden

Hoffentlich hilft das jemandem!

35
Dean

Ich schreibe eine Regel in web.config aus, nachdem $locationProvider.html5Mode(true) in app.js eingestellt ist. 

Hoffnung, hilft jemandem.

  <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 meiner index.html habe ich dies zu <head> hinzugefügt.

<base href="/">

Vergessen Sie nicht, IIS URL Rewrite auf dem Server zu installieren.

Wenn Sie Web-API und IIS verwenden, funktioniert dies auch, wenn sich Ihre API aufgrund der dritten Eingabe (__code) in www.yourdomain.com/api befindet (dritte Zeile der Bedingung).

259
Yagiz Ozturk

In meinem Fall erhielt ich immer eine 403.14, nachdem ich die korrekten Regeln zum Umschreiben eingerichtet hatte. Es stellt sich heraus, dass ich ein Verzeichnis hatte, das den gleichen Namen wie eine meiner URL-Routen hatte. Nachdem ich die IsDirectory-Überschreibungsregel entfernt hatte, funktionierten meine Routen korrekt. Gibt es einen Fall, in dem das Entfernen der Verzeichnisnegation Probleme verursachen kann? Mir fällt in meinem Fall nichts ein. Ich kann mir nur vorstellen, dass Sie mit Ihrer App ein Verzeichnis durchsuchen können.

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

Das Problem mit nur diesen beiden Bedingungen:

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

ist, dass sie nur funktionieren, solange der {REQUEST_FILENAME}physisch auf der Festplatte vorhanden ist. Dies bedeutet, dass es Szenarien geben kann, in denen eine Anforderung für eine falsch benannte Teilansicht anstelle von 404 die Stammseite zurückgibt, wodurch Winkel zweimal geladen werden würde (und in bestimmten Szenarien eine unendliche Endlosschleife verursachen kann).

Daher werden einige sichere "Rückfall" -Regeln empfohlen, um diese schwer zu behandelnden Probleme zu vermeiden:

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

oder eine Bedingung, die mit einer beliebigen Dateiendung übereinstimmt

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

Der einfachste Weg, den ich gefunden habe, ist die Umleitung der Anforderungen, die 404 auslösen, an den Client. Dies geschieht durch Hinzufügen eines Hashtags, auch wenn $locationProvider.html5Mode(true) eingestellt ist.

Dieser Trick funktioniert für Umgebungen mit mehr Webanwendungen auf derselben Website, für die Einschränkungen der URL-Integrität (externe Authentifizierung) erforderlich sind. Hier ist Schritt für Schritt, wie es geht

index.html

Legen Sie das <base>-Element richtig fest

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

web.config

Zuerst 404 auf eine benutzerdefinierte Seite umleiten, z. B. "Home/Fehler".

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

Home-Controller

Implementieren Sie eine einfache ActionResult-Eingabe, um die Eingabe in eine clientseitige Route zu "übersetzen".

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

Dies ist der einfachste Weg.


Es ist möglich (ratsam?), Die Error-Funktion mit verbesserter Logik zu verbessern, um 404 nur dann an den Client umzuleiten, wenn die URL gültig ist, und den 404 normal auszulösen, wenn auf Client nichts gefunden wird

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

Es ist sinnvoll, die URL nur an den Client umzuleiten, wenn sie mit "/ Neu" oder "/ Show /" beginnt.

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

Dies ist nur ein Beispiel für eine verbesserte Logik. Natürlich hat jede Webanwendung andere Anforderungen

1
Naigel

Ich habe versucht, eine einfache Angular 7-Anwendung für eine Azure-Webanwendung bereitzustellen. Alles funktionierte gut, bis Sie die Seite aktualisiert haben. Dabei wurde mir ein um 500 Fehler verschobener Inhalt präsentiert .. Ich habe sowohl in den Angular-Dokumenten als auch in einigen Foren gelesen, dass ich meiner bereitgestellten Lösung eine web.config-Datei hinzufügen und machen muss Sicher, dass die Regel für das Zurückschreiben der Regel in die Datei index.html übergeht ..__ Nach stundenlangem Frust und Test- und Fehlertests habe ich festgestellt, dass der Fehler ziemlich einfach war: Hinzufügen eines Tags um mein Dateimarkup.

0
Kelson Martins