htaccess-Umleitung für Winkelrouten


73

Ich habe eine eckige Anwendung mit mehreren Routen, wie zum Beispiel:

site.com/
site.com/page
site.com/page/4

Wenn Sie den HTML5-Routing-Modus von Angular verwenden, werden diese korrekt aufgelöst, wenn Sie in der Anwendung auf Links zu ihnen klicken. Bei einer harten Aktualisierung treten jedoch natürlich 404 Fehler auf. Um dies zu beheben, habe ich versucht, ein grundlegendes htaccess-Umschreiben zu implementieren.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_METHOD} !OPTIONS
RewriteRule ^(.*)$ index.html [L]

Dies funktioniert jedoch für die Winkelanforderungen, wenn ich versuche, Skripte zu laden oder Ajax-Aufrufe in meiner Domäne zu tätigen, z.

<script src="/app/programs/script.js"></script>

Dieses Skript wird nicht geladen - die Anforderung wird umgeleitet und es wird versucht, die Seite index.html zu laden, da der .htaccess der Ansicht ist, dass die Anforderung umgeleitet werden sollte - ohne zu wissen, dass diese Datei vorhanden ist, und die Datei anstelle der Umleitung zu laden.

Gibt es eine Möglichkeit, dass der htaccess die Anforderung nur dann an index.html (mit den Ansichtsparametern) umleitet, wenn es keine tatsächliche Datei gibt, in die aufgelöst werden soll?


Ist /app/programs/script.jseine gültige Datei?
Anubhava

Ja, ohne meinen aktuellen .htaccess (wie in der Frage) wird diese Datei ordnungsgemäß aufgelöst.
Lucas Penney

Dieser Trick funktioniert auch bei Angular 2.
Ashish Doneriya

Antworten:


149

Verwenden Sie einen Ausschnitt wie:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) /index.html [NC,L]

Dies springt zur eigentlichen Ressource, falls vorhanden, und zu index.htmlallen AngularJS-Routen.


1
Dies ist fast perfekt - es scheint keine Routen mit Parametern zu verarbeiten, zum Beispiel site.com/page/4, obwohl ich nicht sicher bin, warum.
Lucas Penney

1
Es stellte sich heraus, dass dies gut funktionierte - ich hatte nur einige Dateiverweise ohne führenden Schrägstrich (/) und versuchte daher, in Routen mit Parametern relativ aufzulösen.
Lucas Penney

2
@rajasaur vielen Dank - deshalb liebe ich Stackoverflow. Hat mir geholfen, schnell zu lösen, was ich dachte, ich würde die ganze Nacht wach sein, um es herauszufinden.
Jamie

2
Wo und wie legen Sie diese htaccess-Datei ab?
John Andrews

1
Hallo, in meinem Fall habe ich http://www.domain.com/dashboard. Also die URL hat /dashboarddann nur ich möchte das Winkelprojekt öffnen. Bitte helfen Sie mir, wie man .htaccessfür dasselbe schreibt . Eigentlich habe ich 2 verschiedene Winkelprojekte. 1. wird gerendert http://www.domain.comund 2. sollte weiterlaufen http://www.domain.com/dashboard.
Anil Kumar Pandey

20

Es liegt ein Problem vor, wenn die App eine directiveVorlagendatei angefordert hat , die Datei jedoch fehlt . In einigen Fällen verursachte es App angefordert mehrere Skriptdatei in der index.html.

Wir sollten eine 404Antwort anstelle einer index.htmlDatei senden, wenn die Datei nicht vorhanden ist. Also füge ich ein einfaches Regex-Muster hinzu, um fehlende Dateianforderungen zu identifizieren.

RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# If the requested pattern is file and file doesn't exist, send 404
RewriteCond %{REQUEST_URI} ^(\/[a-z_\-\s0-9\.]+)+\.[a-zA-Z]{2,4}$
RewriteRule ^ - [L,R=404]

# otherwise use history router
RewriteRule ^ /index.html

Wenn die Datei nicht vorhanden ist, RewriteRule ^ - [L,R=404]kann ich sie dann mithilfe von RewriteRule ^ /index.htmloder auf index.html umleiten RewriteRule ^ - [L,R=/index.html]? Ich bin in einer Appserver-Umgebung und die Pfade brechen ziemlich oft. Nicht an solche Änderungen in .htaccess gewöhnt, sondern nur 404 nach index.html umleiten.
Gary

Ja, Sie können den 404-Teil überspringen, aber worum geht es? Dieser .htaccessAnsatz ist für das Fehlen einer Asset- / Vorlagendatei in eckigen Anweisungen vorgesehen, nicht für das Fehlen eines Pfads. Wenn Sie den fehlenden Pfad behandeln möchten, sollten Sie den Router-Anbieter selbst konfigurieren oder Router-Ereignisse verwenden.
Port115

Ich möchte kein 404-Handle für den .htaccess. Ich möchte all das mit der eckigen Datei index.html erledigen
Gary

+1 für die einzige Antwort, die %{DOCUMENT_ROOT}in der RewriteCond verwendet wird und die erforderlich ist, wenn Sie sich in einem VirtualHost befinden - andernfalls ist die Bedingung niemals erfüllt!
not2savvy

6

Die Lösung eines armen Mannes (ohne mod_rewrite):

ErrorDocument 404 /index.html

5

In meinem Fall erstelle ich eine .htaccess-Datei wie unten

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) ./index.html [NC,L]

gerade hinzugefügt . vor /index.html und fügen Sie diese Datei in meiner Domain wie https://example.com/subfolder hinzu und es funktioniert gut


3

Überprüfen Sie diesen Link: https://stackoverflow.com/a/49455101/5899936 Erstellen Sie eine .htaccessDatei im Stammordner und fügen Sie diese in den Ordner ein.htaccess

 <IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

Danke, es hat bei mir funktioniert. Wenn es sich um ein Unterverzeichnis handelt, fügen Sie einfach RewriteBase /SubDirstattRewriteBase /
sree

1

Ich werde eine weitere detaillierte htaccess-Datei bereitstellen, falls Sie Folgendes benötigen:

  • Betrachten Sie die baseUrl- und Standardindexdatei
  • Entfernen Sie den führenden Schrägstrich, um Folgendes zu verwalten: params

Hier ist mein Erfolg, sehr nah, aber genauer:

DirectoryIndex index.html
RewriteEngine on
RewriteBase /subDir
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*) index.html [NC,L]

0

In meinem Fall brauchten wir eine .htaccessKonfiguration mit mehr Funktionen , wie zum Beispiel:

  • Erzwingen des HTTPS-Protokolls (unten auskommentiert).
  • Übersetzung des AuthorizationHeaders in eine HTTP_AUTHORIZATIONUmgebungsvariable.
  • Cross-Origin Resource Sharing (CORS).
  • Und deaktiviertes Caching für bestimmte Formate (ebenfalls auskommentiert).

# If mod_rewrite is not present.
<IfModule !mod_rewrite.c>
  FallbackResource /index.html
</IfModule>

<IfModule mod_rewrite.c>
  RewriteEngine On
  # Prefix for all rewritten routes ("index.html" gets "/index.html").
  RewriteBase /

  # Redirects to HTTPS protocol (once uncommented).
  #
#  RewriteCond %{HTTPS} !on
#  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]

  # Make sure Authorization HTTP header is available.
  RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # Allows access to existing files or dirs.
  RewriteCond %{REQUEST_FILENAME} -s [OR]
  RewriteCond %{REQUEST_FILENAME} -l [OR]
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule ^.*$ - [NC,L]

  # Prevents treating the main-script as a route.
  RewriteRule ^index\.html$ - [L]
  # Redirect anything else to main-script
  RewriteRule ^(.*) index.html [NC,L]
</IfModule>

# Enable Cross-Origin Resource Sharing (CORS)
#
<IfModule mod_headers.c>
  Header merge Vary Origin

  # Allows any origin (just like "*", but works in more cases)
  SetEnvIf Origin "^(http(s)?://[^/:]*(?::\d{1,5})?)?" REQUEST_ORIGIN=$1
  Header always append Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN

  Header always set Access-Control-Allow-Credentials "true"
  Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
  Header always set Access-Control-Allow-Headers "*"
  Header always set Access-Control-Expose-Headers "*"
</IfModule>

# Disables Browser caching for production (edit pattern as you wish).
#
#<FilesMatch "\.(html|htm|js|json|css)$">
#   <IfModule mod_headers.c>
#       FileETag None
#       Header unset ETag
#       Header unset Pragma
#       Header unset Cache-Control
#       Header unset Last-Modified
#       Header set Pragma "no-cache"
#       Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
#       Header set Expires "Mon, 10 Apr 1972 00:00:00 GMT"
#   </IfModule>
#</FilesMatch>

Hinweis: Wir verwenden [L]stattdessen, [L,R=301]da letzteres dazu führt, dass der Browser Weiterleitungen dauerhaft zwischenspeichert (und selbst wenn diese Route eines Tages eine Datei ist, wird sie trotzdem umgeleitet).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.