Patrząc na komentarze do zaakceptowanej odpowiedzi i ogólny charakter tego pytania („nie działa”), pomyślałem, że to może być dobre miejsce na ogólne wyjaśnienia dotyczące kwestii tutaj poruszanych. Tak więc ta odpowiedź ma służyć jako podstawowe informacje / opracowanie na temat konkretnego przypadku użycia PO. Proszę o wyrozumiałość.
Po stronie serwera a po stronie klienta
Pierwszą ważną rzeczą do zrozumienia jest to, że obecnie istnieją 2 miejsca, w których adres URL jest interpretowany, podczas gdy w „dawnych czasach” było tylko jedno. W przeszłości, gdy życie było proste, niektórzy użytkownicy wysyłali żądanie http://example.com/about
do serwera, który sprawdzał część ścieżki adresu URL, ustalał, że użytkownik żąda strony z informacjami, a następnie odsyła tę stronę.
Dzięki routingowi po stronie klienta, który zapewnia React-Router, sprawy są mniej proste. Początkowo klient nie ma jeszcze załadowanego kodu JS. Tak więc pierwsze żądanie zawsze będzie skierowane do serwera. Spowoduje to zwrócenie strony zawierającej znaczniki skryptu potrzebne do załadowania React i React Router itp. Faza 2 rozpoczyna się dopiero po załadowaniu tych skryptów. W fazie 2, gdy użytkownik kliknie na przykład link nawigacyjny „O nas”, adres URL zostanie zmieniony tylko lokalnie na http://example.com/about
(jest to możliwe dzięki History API), ale nie jest wysyłane żadne żądanie do serwera. Zamiast tego React Router robi swoje po stronie klienta, określa, który widok React ma być renderowany i renderuje go. Zakładając, że twoja strona about nie musi wykonywać żadnych wywołań REST, to już zostało zrobione. Przeszedłeś z Home na O nas bez wywoływania żadnego żądania serwera.
Tak więc w zasadzie po kliknięciu łącza uruchamiany jest skrypt JavaScript, który manipuluje adresem URL w pasku adresu, bez powodowania odświeżania strony, co z kolei powoduje, że React Router wykonuje przejście strony na kliencie -strona.
Ale teraz zastanów się, co się stanie, jeśli skopiujesz i wkleisz adres URL w pasku adresu i wyślesz go e-mailem do znajomego. Twój znajomy nie wczytał jeszcze Twojej witryny. Innymi słowy, wciąż jest w fazie 1. Na jej komputerze nie działa jeszcze React Router. Jej przeglądarka wyśle więc żądanie serwera do http://example.com/about
.
I tu zaczynają się twoje kłopoty. Do tej pory mogłeś ujść na sucho po prostu umieszczając statyczny kod HTML w webroocie swojego serwera. Ale to dałoby 404
błędy dla wszystkich innych adresów URL na żądanie z serwera. Te same adresy URL działają dobrze po stronie klienta, ponieważ React Router wykonuje za ciebie routing, ale nie działają po stronie serwera, chyba że sprawisz, że twój serwer zrozumiał ich.
Łączenie routingu po stronie serwera i klienta
Jeśli chcesz, aby adres URL http://example.com/about
działał zarówno po stronie serwera, jak i klienta, musisz skonfigurować dla niego trasy zarówno po stronie serwera, jak i klienta. Ma sens, prawda?
I tu zaczynają się twoje wybory. Rozwiązania wahają się od całkowitego ominięcia problemu, poprzez ścieżkę typu catch-all, która zwraca kod HTML ładowania początkowego, po podejście całkowicie izomorficzne, w którym zarówno serwer, jak i klient uruchamiają ten sam kod JS.
.
Całkowite ominięcie problemu: Hash History
Z Hash History zamiast Historia przeglądarki, Twój adres URL strony z informacjami będzie wyglądał mniej więcej tak: http://example.com/#/about
Część po symbolu skrótu (#
) nie jest wysyłana na serwer. Tak więc serwer widzi tylko http://example.com/
i wysyła stronę indeksu zgodnie z oczekiwaniami. React-Router pobierze część #/about
i wyświetli właściwą stronę.
Wady:
- „brzydkie” adresy URL
- W tym podejściu renderowanie po stronie serwera nie jest możliwe. Jeśli chodzi o optymalizację pod kątem wyszukiwarek (SEO), Twoja witryna składa się z jednej strony, na której nie ma prawie żadnej treści.
.
Złap wszystkie
Dzięki takiemu podejściu korzystasz z historii przeglądarki, ale po prostu konfigurujesz catch-all na serwerze, który wysyła /*
do index.html
, skutecznie dając taką samą sytuację, jak w przypadku historii skrótów. Masz jednak czyste adresy URL i możesz później ulepszyć ten schemat bez konieczności unieważniania wszystkich ulubionych przez użytkownika.
Wady:
- Bardziej złożony w konfiguracji
- Nadal brak dobrego SEO
.
Hybrydowy
W podejściu hybrydowym rozwijasz scenariusz typu catch-all, dodając określone skrypty dla określonych tras. Możesz stworzyć proste skrypty PHP, które będą zwracały najważniejsze strony Twojej witryny z dołączoną treścią, aby Googlebot mógł przynajmniej zobaczyć, co jest na Twojej stronie.
Wady:
- Jeszcze bardziej skomplikowana konfiguracja
- Tylko dobre SEO dla tych tras, które traktujesz w szczególny sposób
- Powielanie kodu do renderowania treści na serwerze i kliencie
.
Izomorficzny
Co się stanie, jeśli użyjemy Node JS jako naszego serwera, aby móc uruchomić ten sam kod JS na obu końcach? Teraz mamy wszystkie nasze trasy zdefiniowane w jednej konfiguracji routera React-router i nie musimy duplikować naszego kodu renderującego. To jest, że tak powiem, „święty Graal”. Serwer wysyła dokładnie takie same znaczniki, jakie otrzymalibyśmy, gdyby przejście strony miało miejsce na kliencie. To rozwiązanie optymalne z punktu widzenia SEO.
Wady:
- Serwer musi (być w stanie) uruchamiać JS. Eksperymentowałem z Javą i.c.w. Nashorn, ale dla mnie to nie działa. W praktyce oznacza to głównie konieczność korzystania z serwera opartego na Node JS.
- Wiele trudnych problemów środowiskowych (używanie
window
po stronie serwera itp.)
- Stroma krzywa uczenia się
.
Którego powinienem użyć?
Wybierz ten, który ujdzie Ci na sucho. Osobiście uważam, że wszystko jest dość proste do skonfigurowania, więc to byłoby moje minimum. Ta konfiguracja pozwala z czasem ulepszać rzeczy. Jeśli używasz już Node JS jako platformy serwerowej, zdecydowanie zbadam tworzenie aplikacji izomorficznej. Tak, na początku jest to trudne, ale kiedy już to zrozumiesz, jest to w rzeczywistości bardzo eleganckie rozwiązanie problemu.
Więc w zasadzie dla mnie byłby to decydujący czynnik. Jeśli mój serwer działa na Node JS, byłbym izomorficzny; w przeciwnym razie wybrałbym rozwiązanie typu „catch-all” i po prostu je rozszerzyłem (rozwiązanie hybrydowe) w miarę upływu czasu i wymagań SEO.
Jeśli chcesz dowiedzieć się więcej o renderowaniu izomorficznym (zwanym również „uniwersalnym”) w React, znajdziesz kilka dobrych samouczków na ten temat:
Ponadto, aby zacząć, polecam zapoznać się z kilkoma zestawami startowymi. Wybierz taki, który pasuje do twoich wyborów dla stosu technologii (pamiętaj, że React to tylko V w MVC, potrzebujesz więcej rzeczy, aby zbudować pełną aplikację). Zacznij od przyjrzenia się tej opublikowanej przez samego Facebooka:
Lub wybierz jeden z wielu przez społeczność. Jest teraz fajna strona, która próbuje zindeksować je wszystkie:
Zacząłem od tych:
Obecnie używam domowej wersji uniwersalnego renderowania, która została zainspirowana dwoma powyższymi zestawami startowymi, ale są one już nieaktualne.
Powodzenia w Twojej misji!
person
Stijn de Witt
schedule
14.04.2016
#
? Dziękuję Ci! - person SudoPlz   schedule 06.06.2015index.html
. Dzięki temuindex.html
zostanie trafiony bez względu na wszystko. - person Trevor Hutto   schedule 30.07.2016