webentwicklung-frage-antwort-db.com.de

AngularJS HTML5-Modus - Wie funktionieren direkte Links ohne serverspezifische Änderungen?

Hinweis: Diese Frage könnte auch lauten:

So unterstützen Sie das Lesezeichen von clientseitigen MVC-Frameworks ohne Hashbang in Java.

Ich ändere eine angular App, die hashtags verwendet, auf eine, die html5mode. Ich habe erfolgreich eingestellt

$locationProvider.html5Mode(true);

Und alle Links von der Landing Page (index.html) funktionieren einwandfrei.

Das Problem ist, wenn Teil-URLs direkt referenziert werden, erhalte ich natürlich eine 404, da die Serverendpunktdefinitionen nicht an clientseitig definierte Routen gekoppelt sind.

Ohne HTML5 erhalten wir also nicht SEO-freundliche Hashbangs, aber damit können wir nichts anderes als die Zielseite (die Seite, die eckig bootet) als Lesezeichen speichern.

Warum funktioniert es, wenn zuerst eine Standard-Zielseite (index.html) angefordert wird, z. B. htpp: //meinedomain.com/:

  1. Browser fordert index.html vom Server an
  2. Der Server gibt index.html zurück und der Browser lädt das angular Framework
  3. URL-Änderungen werden an den clientseitigen Router gesendet und die richtigen Teile werden geladen.

Warum funktioniert es nicht, wenn (ie) http://mydomain.com/foo direkt vom Browser angefordert wird:

  1. Der Browser fordert mydomain/foo vom Server an.
  2. Ressource existiert nicht
  3. Server gibt 404 zurück

In dieser Geschichte fehlt etwas, ich weiß nur nicht was. Hier sind die einzigen zwei Antworten, die ich sehen kann ...

  • Es ist beabsichtigt. Soll es so funktionieren? Diese Benutzer müssen immer auf der bootstrap page des Client-MVC-Frameworks (normalerweise index.html) landen und dann von dort aus navigieren. Dies ist nicht ideal, da der Status nicht gespeichert werden kann und es keine Möglichkeit gibt, Lesezeichen zu setzen ... ganz zu schweigen von krabbeln.
  • Serverlösung. Wurde dies mit einem serverseitigen Trick umgangen? Geben Sie beispielsweise bei allen Anforderungen index.html zurück und rufen Sie sofort den Router mit zusätzlichem Kontext auf. Wenn ja, ist dies gegen das Ziel, dass AngularJS vollständig clientseitig ist und wie ein Hack wirkt.
45

In der AngularJS-Dokumentation wird dies tatsächlich erwähnt

Serverseitig In diesem Modus muss die URL serverseitig umgeschrieben werden. Grundsätzlich müssen Sie alle Ihre Links zum Einstiegspunkt Ihrer Anwendung (z. B. index.html) umschreiben.

In diesem Fall besteht eine Java-basierte Lösung darin, dem Server mitzuteilen, dass alle URLs der Datei index.html zugeordnet werden sollen. Dies kann in jedem HTTP-Server oder Container erfolgen. Ich habe dies mit Java/Servet implementiert, da ich möchte, dass meine Anwendung HTTP-Server-unabhängig ist (dh Apache versus NginX oder nur Tomcat/JBoss).

In web.xml:

  <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
      <servlet-name>StaticServlet</servlet-name>
      <jsp-file>/index.jsp</jsp-file>
  </servlet>

  <servlet-mapping>
      <servlet-name>StaticServlet</servlet-name>
      <url-pattern>/app</url-pattern>
  </servlet-mapping>

Und index.jsp sieht einfach so aus:

<%@ include file="index.html" %>

Fügen Sie dem Tag in index.html Folgendes hinzu:

<base href="/app" />
39

Ich habe einige Zeit damit verbracht, über meine PHP Site nachzudenken. Ich hänge meinen gesamten serverseitigen Code vom /api ab. Hier ist die Lösung, die ich durch die Aktualisierung meiner Apache-Konfiguration gefunden habe:

RewriteEngine on
#let the php framework do its thing
RewriteRule ^(api/.*)$ index.php?url=$1 [QSA,L,NC]
#let angular do its thing
RewriteCond %{REQUEST_FILENAME} !-f      
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.html [NC,L]

Ich habe unter Verwendung des Flight PHP Framework unter http://www.awnage.com/2013/10/10/taking-flight-with-angularjs) geschrieben, wie ich das gemacht habe /

3
Awnage