Angesichts der Kommentare zur akzeptierten Antwort und des allgemeinen Charakters dieser Frage („funktioniert nicht“) dachte ich, dass dies ein guter Ort für einige allgemeine Erklärungen zu den hier behandelten Themen sein könnte. Diese Antwort ist also als Hintergrundinformation / Ausarbeitung des spezifischen Anwendungsfalls des OP gedacht. Bitte bei mir tragen.
Serverseitig gegen Clientseite
Das Erste, was man darüber verstehen sollte, ist, dass es jetzt zwei Stellen gibt, an denen die URL interpretiert wird, während es früher nur eine gab. In der Vergangenheit, als das Leben einfach war, hat ein Benutzer eine Anfrage http://example.com/about
an den Server gesendet, der den Pfadteil der URL überprüft, festgestellt hat, dass der Benutzer die Info-Seite angefordert hat, und diese Seite dann zurückgesendet.
Beim clientseitigen Routing, das React-Router bietet, sind die Dinge weniger einfach. Zunächst ist auf dem Client noch kein JS-Code geladen. Die allererste Anfrage wird also immer an den Server gerichtet. Daraufhin wird eine Seite zurückgegeben, die die zum Laden von React und React Router usw. erforderlichen Skript-Tags enthält. Erst wenn diese Skripte geladen wurden, wird Phase 2 gestartet. Wenn der Benutzer in Phase 2 beispielsweise auf den Navigationslink "Über uns" klickt, wird die URL nur lokal in http://example.com/about
(ermöglicht durch die Verlaufs-API ) geändert , es wird jedoch keine Anforderung an den Server gestellt. Stattdessen erledigt React Router seine Aufgabe auf der Clientseite, bestimmt, welche React-Ansicht gerendert werden soll, und rendert sie. Angenommen, Ihre About-Seite muss keine REST-Aufrufe ausführen, ist dies bereits geschehen. Sie sind von "Home" zu "Über uns" gewechselt, ohne dass eine Serveranforderung ausgelöst wurde.
Wenn Sie also auf einen Link klicken, wird Javascript ausgeführt, das die URL in der Adressleiste manipuliert, ohne eine Seitenaktualisierung zu verursachen , was wiederum dazu führt, dass React Router einen Seitenübergang auf der Clientseite durchführt .
Überlegen Sie nun, was passiert, wenn Sie die URL kopieren, in die Adressleiste einfügen und per E-Mail an einen Freund senden. Ihr Freund hat Ihre Website noch nicht geladen. Mit anderen Worten, sie befindet sich noch in Phase 1 . Auf ihrem Computer läuft noch kein React Router. Ihr Browser wird also eine Serveranfrage an stellen http://example.com/about
.
Und hier beginnt Ihr Ärger. Bis jetzt konnten Sie nur einen statischen HTML-Code auf der Webroot Ihres Servers platzieren. Dies würde jedoch zu 404
Fehlern für alle anderen URLs führen, wenn dies vom Server angefordert wird . Dieselben URLs funktionieren auf der Clientseite einwandfrei , da dort React Router das Routing für Sie ausführt. Auf der Serverseite schlagen sie jedoch fehl, es sei denn, Sie lassen Ihren Server sie verstehen.
Kombination von server- und clientseitigem Routing
Wenn die http://example.com/about
URL sowohl auf der Server- als auch auf der Clientseite funktionieren soll, müssen Sie Routen sowohl auf der Server- als auch auf der Clientseite einrichten. Macht Sinn, oder?
Und hier beginnen Ihre Entscheidungen. Die Lösungen reichen von der Umgehung des Problems über eine Catch-All-Route, die den Bootstrap-HTML-Code zurückgibt, bis hin zum isomorphen Ansatz, bei dem sowohl der Server als auch der Client denselben JS-Code ausführen.
.
Das Problem insgesamt umgehen: Hash-Verlauf
Mit Hash-Verlauf anstelle von Browser-Verlauf sieht Ihre URL für die About-Seite ungefähr so aus:
http://example.com/#/about
Der Teil nach dem #
Symbol hash ( ) wird nicht an den Server gesendet. Der Server sieht http://example.com/
und sendet die Indexseite also nur wie erwartet. React-Router nimmt das #/about
Teil auf und zeigt die richtige Seite an.
Nachteile :
- "hässliche" URLs
- Serverseitiges Rendern ist mit diesem Ansatz nicht möglich. In Bezug auf die Suchmaschinenoptimierung (SEO) besteht Ihre Website aus einer einzelnen Seite, auf der sich kaum Inhalte befinden.
.
Allheilmittel
Mit diesem Ansatz haben Sie verwenden Browser - Historie, aber nur eine allumfassende auf dem Server einrichten, sendet /*
an index.html
, effektiv Sie viel die gleiche Situation wie mit Hash Geschichte zu geben. Sie haben jedoch saubere URLs und können dieses Schema später verbessern, ohne alle Favoriten Ihres Benutzers ungültig machen zu müssen.
Nachteile :
- Komplexer einzurichten
- Immer noch keine gute SEO
.
Hybrid
Beim hybriden Ansatz erweitern Sie das Catch-All-Szenario, indem Sie bestimmte Skripte für bestimmte Routen hinzufügen. Sie können einige einfache PHP-Skripte erstellen, um die wichtigsten Seiten Ihrer Website mit eingeschlossenem Inhalt zurückzugeben, damit Googlebot zumindest sehen kann, was sich auf Ihrer Seite befindet.
Nachteile :
- Noch komplexer einzurichten
- Nur gute SEO für diese Routen geben Sie die Sonderbehandlung
- Duplizieren von Code zum Rendern von Inhalten auf Server und Client
.
Isomorph
Was ist, wenn wir Node JS als Server verwenden, damit wir an beiden Enden denselben JS-Code ausführen können ? Jetzt haben wir alle unsere Routen in einer einzigen React-Router-Konfiguration definiert und müssen unseren Rendering-Code nicht mehr duplizieren. Dies ist sozusagen 'der heilige Gral'. Der Server sendet genau das gleiche Markup, das wir erhalten würden, wenn der Seitenübergang auf dem Client stattgefunden hätte. Diese Lösung ist in Bezug auf SEO optimal.
Nachteile :
- Der Server muss JS ausführen können (können). Ich habe mit Java icw Nashorn experimentiert, aber es funktioniert nicht für mich. In der Praxis bedeutet dies meistens, dass Sie einen Node JS-basierten Server verwenden müssen.
- Viele knifflige Umweltprobleme (Verwendung
window
auf der Serverseite usw.)
- Steile Lernkurve
.
Welches soll ich verwenden?
Wählen Sie die aus, mit der Sie durchkommen können. Persönlich denke ich, dass das Allheilmittel einfach genug ist, um es einzurichten, also wäre das mein Minimum. Mit diesem Setup können Sie die Dinge im Laufe der Zeit verbessern. Wenn Sie Node JS bereits als Serverplattform verwenden, würde ich auf jeden Fall eine isomorphe App untersuchen. Ja, es ist zunächst schwierig, aber sobald Sie den Dreh raus haben, ist es tatsächlich eine sehr elegante Lösung für das Problem.
Für mich wäre das also der entscheidende Faktor. Wenn mein Server auf Node JS läuft, würde ich isomorph werden. Andernfalls würde ich mich für die Catch-All-Lösung entscheiden und sie im Laufe der Zeit erweitern und die SEO-Anforderungen erfordern.
Wenn Sie mehr über isomorphes (auch als "universell" bezeichnetes) Rendering mit React erfahren möchten, gibt es einige gute Tutorials zu diesem Thema:
Um Ihnen den Einstieg zu erleichtern, empfehle ich Ihnen, sich einige Starter-Kits anzusehen. Wählen Sie eine aus, die Ihren Auswahlmöglichkeiten für den Technologie-Stack entspricht (denken Sie daran, React ist nur das V in MVC, Sie benötigen mehr Material, um eine vollständige App zu erstellen). Schauen Sie sich zunächst die von Facebook selbst veröffentlichte an:
Oder wählen Sie eine der vielen von der Community. Es gibt jetzt eine schöne Seite, die versucht, alle zu indizieren:
Ich habe mit diesen angefangen:
Derzeit verwende ich eine selbstgebraute Version des universellen Renderings, die von den beiden oben genannten Starter-Kits inspiriert wurde, aber jetzt veraltet ist.
Viel Glück bei deiner Suche!