React-adresy URL routera nie działają podczas odświeżania lub ręcznego pisania

Używam react-routera i działa dobrze, gdy klikam na przyciski linku, ale kiedy odświeżam moją stronę internetową, nie ładuje się to, co chcę.

Na przykład, jestem w localhost/joblist i wszystko jest w porządku, ponieważ przyjechałem tutaj naciskając link. Ale jak odświeżę stronę dostaję:

Cannot GET /joblist

Domyślnie, to nie działa w ten sposób. Początkowo miałem mój adres URL jako localhost/#/ i localhost/#/joblist i działały idealnie. Ale nie podoba mi się ten rodzaj adresu URL, więc staram się to usunąć #, Napisałam:

Router.run(routes, Router.HistoryLocation, function (Handler) {
 React.render(<Handler/>, document.body);
});

Ten problem nie występuje z localhost/, ten zawsze zwraca to, co chcę.

EDIT: Ta aplikacja jest jednostronicowa, więc /joblist nie musi o nic pytać na żadnym serwerze.

EDIT2: mój cały router.

var routes = (
    <Route name="app" path="/" handler={App}>
        <Route name="joblist" path="/joblist" handler={JobList}/>
        <DefaultRoute handler={Dashboard}/>
        <NotFoundRoute handler={NotFound}/>
    </Route>
);

Router.run(routes, Router.HistoryLocation, function (Handler) {
  React.render(<Handler/>, document.body);
});
Author: B--rian, 2015-01-13

30 answers

patrząc na komentarze dotyczące przyjętej odpowiedzi i ogólny charakter tego pytania ("nie pracuj"), pomyślałem, że może to być dobre miejsce na ogólne wyjaśnienia dotyczące kwestii, które tu dotyczą. Tak więc ta odpowiedź jest przeznaczona jako info / opracowanie na temat konkretnego przypadku użycia OP. proszę o cierpliwość ze mną.

Po stronie serwera vs po stronie klienta

Pierwszą ważną rzeczą do zrozumienia jest to, że są teraz 2 miejsca, w których adres URL jest interpretowany, natomiast w "dawnych czasach" było tylko 1. W przeszłości, gdy życie było proste, niektórzy użytkownicy wysyłali Zapytanie o http://example.com/about do serwera, który sprawdzał część ścieżki adresu URL, ustalał, że użytkownik żądał strony about, a następnie odsyłał tę stronę.

Z routingiem po stronie klienta, który zapewnia React-Router, rzeczy są mniej proste. Na początku klient nie ma jeszcze wczytanego kodu JS. Więc pierwsze żądanie zawsze będzie do serwera. Które następnie zwróci strona, która zawiera potrzebne znaczniki skryptu do ładowania Reacta i Reacta routera itp. Dopiero po załadowaniu tych skryptów rozpoczyna się faza 2. W fazie 2, gdy użytkownik kliknie na link nawigacyjny "O nas", na przykład, adres URL jest zmieniany lokalnie tylko na http://example.com/about (możliwe dzięki API historii ), ale nie jest wysyłane żadne żądanie do serwera. Zamiast tego, React Router robi swoje po stronie klienta, określa, który Widok Reacta ma być renderowany i renderuje go. Zakładając, że o strona nie musi wykonywać żadnych połączeń REST, to już zrobione. Przeszedłeś z domu do O nas bez żadnego żądania serwera.

Więc po kliknięciu linku uruchamiany jest Javascript, który manipuluje adresem URL na pasku adresu, bez powodowania odświeżania strony , co z kolei powoduje, że React Router wykonuje Przejście strony po stronie klienta.

Ale teraz zastanów się, co się stanie, jeśli skopiujesz i wkleisz adres URL w pasku adresu i e-mail to przyjacielowi. Twój znajomy nie załadował jeszcze Twojej strony. Innymi słowy, wciąż jest w fazie 1. Żaden Router Reacta nie działa jeszcze na jej komputerze. Więc jej przeglądarka wyśle żądanie serwera do http://example.com/about.

I tu zaczyna się twój kłopot. Do tej pory, można uciec z po prostu umieszczenie statycznego HTML w webroot serwera. Ale to dałoby 404 błędy dla wszystkich innych adresów URL , gdy zażądano tego z serwera . Te same adresy URL działają dobrze Po stronie klienta, ponieważ router Reactowy wykonuje routing za ciebie, ale zawodzą Po stronie serwera, chyba że sprawisz, że serwer je zrozumie.

Łą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 po stronie klienta, musisz skonfigurować dla niego trasy zarówno po stronie serwera, jak i po stronie klienta. To ma sens, prawda?

I tu zaczynają się Twoje wybory. Rozwiązania wahają się od ominięcia problem w ogóle, poprzez catch-all route, który zwraca Bootstrap HTML, do pełnego izomorficznego podejścia, gdzie zarówno serwer, jak i klient uruchamiają ten sam kod JS.

.

Ominięcie problemu: Historia hashów

Z Historia Hasha zamiast historia przeglądarki , Twój adres URL strony about będzie wyglądał mniej więcej tak: http://example.com/#/about Część po symbolu hash (#) nie jest wysyłana do serwera. Więc serwer widzi tylko http://example.com/ i wysyła strona indeksu zgodnie z oczekiwaniami. React-Router odbierze #/about część i pokaże poprawną stronę.

Wady :

  • 'brzydkie' adresy URL
  • renderowanie po stronie serwera nie jest możliwe przy takim podejściu. Jeśli chodzi o optymalizację pod kątem wyszukiwarek (SEO), Twoja strona internetowa składa się z jednej strony z prawie żadną zawartością na niej.

.

Catch-all

Dzięki temu podejściu, używasz historii przeglądarki, ale po prostu skonfiguruj catch-all NA serwer, który wysyła /* do index.html, skutecznie dając Ci taką samą sytuację jak w historii hashów. Masz jednak czyste adresy URL i możesz poprawić ten schemat później bez konieczności unieważniania wszystkich ulubionych użytkowników.

Wady :

  • bardziej skomplikowane do skonfigurowania
  • wciąż brak dobrego SEO

.

Hybryda

W podejściu hybrydowym rozwijasz scenariusz catch-all, dodając określone skrypty dla konkretnych trasy. Możesz zrobić kilka prostych skryptów PHP, aby zwrócić Najważniejsze strony witryny z zawartością, więc Googlebot może przynajmniej zobaczyć, co znajduje się na twojej stronie.

Wady :

  • jeszcze bardziej skomplikowana konfiguracja
  • tylko dobre SEO dla tych tras, które dajesz specjalne traktowanie
  • powielanie kodu do renderowania zawartości na serwerze i kliencie

.

Izomorficzny

Co jeśli użyjemy Node JS jako naszego serwera więc czy można uruchomić ten sam kod JS na obu końcach? Teraz mamy wszystkie nasze trasy zdefiniowane w jednej konfiguracji react-router i nie musimy powielać naszego kodu renderującego. To jest "Święty Graal", że tak powiem. Serwer wysyła dokładnie te same znaczniki, z którymi skończylibyśmy, gdyby nastąpiło przejście strony na kliencie. To rozwiązanie jest optymalne pod względem SEO.

Wady :

  • Serwer musi (być w stanie) uruchomić JS. Eksperymentowałem z Javą i. c. w. Nashorn, ale mi to nie działa. W praktyce oznacza to głównie, że musisz użyć serwera opartego na węzłach 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 Ci ujdzie na sucho. Osobiście uważam, że catch-all jest na tyle prosty, aby ustawić, więc byłoby to moje minimum. Ta konfiguracja pozwala na poprawę rzeczy w czasie. Jeśli używasz już Node JS jako twoja platforma serwerowa, zdecydowanie zbadałbym robiąc izomorficzną aplikację. Tak, na początku jest ciężko, ale kiedy już się przyzwyczaisz, jest to bardzo eleganckie rozwiązanie problemu.

Więc w zasadzie, dla mnie, to byłby decydujący czynnik. Jeśli mój serwer działa na Node JS, poszedłbym izomorficznie; w przeciwnym razie, poszedłbym na rozwiązanie Catch-all i po prostu rozszerzył na nim (rozwiązanie hybrydowe) w miarę postępu czasu i wymagań SEO tego wymagają.

Jeśli chcesz dowiedzieć się więcej o renderowanie izomorficzne (zwane również "uniwersalnym") z Reactem, istnieje kilka dobrych samouczków na ten temat: {]}

Również, aby zacząć, polecam spojrzeć na kilka zestawów startowych. Wybierz taki, który pasuje do Twoich wyborów dotyczących technologii stos (pamiętaj, React to tylko V W MVC, Potrzebujesz więcej rzeczy, aby zbudować pełną aplikację). Zacznij od tego, który sam opublikował Facebook:

Lub wybrać jedną z wielu przez społeczność. Jest teraz fajna strona, która stara się indeksować wszystkie z nich:

Zacząłem od tych:

Obecnie używam domowej wersji uniwersalnego renderingu, która została zainspirowana dwoma powyższymi zestawami startowymi, ale są one obecnie nieaktualne.

Powodzenia w misji!

 1284
Author: Stijn de Witt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-22 11:11:00

Odpowiedzi tutaj są bardzo pomocne, to, co działało dla mnie, to skonfigurowanie mojego serwera Webpack, aby oczekiwał tras.

devServer: {
   historyApiFallback: true,
   contentBase: './',
   hot: true
},

Historia jest tym, co naprawiło ten problem dla mnie. Teraz routing działa poprawnie i mogę odświeżyć stronę lub wpisać adres URL bezpośrednio. Nie musisz się martwić o pracę na serwerze węzłów. Ta odpowiedź oczywiście działa tylko wtedy, gdy używasz webpack.

EDIT: zobacz moją odpowiedź tutaj, aby uzyskać bardziej szczegółowy powód, dla którego jest to konieczne: https://stackoverflow.com/a/37622953/5217568

 137
Author: jmancherje,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-15 03:13:12

Możesz zmienić swój plik .htaccess i wstawić to:

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

Używam react: "^16.12.0" i react-router: "^5.1.2" Ta metoda jest Catch-all I jest prawdopodobnie najprostszym sposobem, aby zacząć.

 111
Author: BrahimS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-22 11:00:02

Dla Użytkowników Reactowego Routera V4:

Jeśli spróbujesz rozwiązać ten problem techniką historii Hash wymienioną w innych odpowiedziach, zauważ, że

<Router history={hashHistory} >

Nie działa w V4, Proszę użyć HashRouter zamiast:

import { HashRouter } from 'react-router-dom'

<HashRouter>
  <App/>
</HashRouter>

Reference: HashRouter

 75
Author: user2875289,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-23 15:33:02

Użyłem create-react-app, aby stworzyć stronę internetową i miałem ten sam problem przedstawiony tutaj. Używam BrowserRouting z pakietu react-router-dom. Działam na serwerze Nginx i to, co dla mnie rozwiązało, to dodanie do /etc/nginx/yourconfig.conf

location / {
  if (!-e $request_filename){
    rewrite ^(.*)$ /index.html break;
  }
}

Co odpowiada dodaniu do .htaccess W przypadku, gdy używasz Appache

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

Wydaje się, że jest to również rozwiązanie zaproponowane przez samego Facebook ' a i można je znaleźć tutaj

 44
Author: Aidin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-06 08:28:53

W Twoim indeksie.html head, dodaj:

<base href="/">
<!-- This must come before the css and javascripts -->

Następnie podczas pracy z Webpack dev server użyj tego polecenia.

webpack-dev-server --mode development --hot --inline --content-base=dist --history-api-fallback

--history-api-fallback jest ważną częścią

 32
Author: Efe Ariaroo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-01 14:26:39

Router może być wywoływany na dwa różne sposoby, w zależności od tego, czy nawigacja odbywa się na kliencie, czy na serwerze. Masz go skonfigurowany do pracy po stronie klienta. Kluczowym parametrem jest drugi po metodzie run , location.

Gdy używasz komponentu React Router Link, blokuje on nawigację w przeglądarce i wywołuje transitionTo, aby wykonać nawigację po stronie klienta. Używasz HistoryLocation, więc używa HTML5 history API, aby zakończyć iluzję nawigacja poprzez symulację nowego adresu URL na pasku adresu. Jeśli używasz starszych przeglądarek, to nie będzie działać. Trzeba by użyć komponentu HashLocation.

Po naciśnięciu odśwież, omija się cały kod Reacta i routera. Serwer pobiera żądanie /joblist I musi coś zwrócić. Na serwerze musisz przekazać żądaną ścieżkę do metody run, aby renderowała prawidłowy widok. Możesz użyć tej samej mapy trasy, ale prawdopodobnie będziesz potrzebować inne wywołanie do Router.run. Jak wskazuje Charles, możesz użyć przepisywania adresów URL, aby to obsłużyć. Inną opcją jest użycie węzła.js server obsługuje wszystkie żądania i przekazuje wartość path jako argument location.

W Expressie, na przykład, może wyglądać tak:

var app = express();

app.get('*', function (req, res) { // This wildcard method handles all requests

    Router.run(routes, req.path, function (Handler, state) {
        var element = React.createElement(Handler);
        var html = React.renderToString(element);
        res.render('main', { content: html });
    });
});

Zwróć uwagę, że ścieżka żądania jest przekazywana do run. Aby to zrobić, musisz mieć silnik widoku po stronie serwera, do którego możesz przekazać renderowany HTML. Istnieje wiele innych rozważań przy użyciu renderToString i w uruchamianie Reacta na serwerze. Gdy strona zostanie renderowana na serwerze, gdy aplikacja załaduje się do Klienta, będzie renderowana ponownie, aktualizując renderowany HTML po stronie serwera w razie potrzeby.

 31
Author: Todd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 10:45:56

Jeśli korzystasz z aplikacji react przez AWS Static S3 Hosting & CloudFront

Ten problem pojawił się w odpowiedzi CloudFront z Komunikatem 403 Access Denied, ponieważ oczekiwał, że /some/other/path istnieje w moim folderze S3, ale ta ścieżka istnieje tylko wewnętrznie w routingu Reacta z reactowym routerem.

Rozwiązaniem było skonfigurowanie reguły stron błędów dystrybucji. Przejdź do ustawień CloudFront i wybierz swoją dystrybucję. Następnie przejdź do zakładki "Strony błędów". Klik "Utwórz niestandardową odpowiedź na błąd" i dodaj wpis dla 403, ponieważ jest to kod statusu błędu, który otrzymujemy. Ustaw ścieżkę strony odpowiedzi na /index.html i kod stanu do 200. Efekt końcowy zadziwia mnie swoją prostotą. Strona indeksu jest obsługiwana, ale adres URL jest zachowany w przeglądarce, więc po załadowaniu aplikacji react wykrywa ścieżkę URL i przechodzi do żądanej trasy.

Strony Błędów 403 Rule

 25
Author: th3morg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-23 03:10:45

To może rozwiązać twój problem]}

Miałem również do czynienia z tym samym problemem w aplikacji ReactJS w trybie produkcyjnym. Oto 2 rozwiązanie problemu.

1.Zmień historię routingu na" hashHistory " zamiast browserHistory w miejscu

<Router history={hashHistory} >
   <Route path="/home" component={Home} />
   <Route path="/aboutus" component={AboutUs} />
</Router>

Teraz zbuduj aplikację za pomocą polecenia

sudo npm run build

Następnie umieść folder build w folderze var / www/ , teraz aplikacja działa dobrze z dodaniem # tag w każdym adresie URL. jak

Localhost/ # / home localhost/# / aboutus

Rozwiązanie 2: bez # tagów za pomocą browserHistory,

Ustaw swoją historię = {browserHistory} w routerze, a teraz zbuduj go za pomocą sudo npm run build.

Musisz utworzyć plik "conf", aby rozwiązać stronę 404 not found, plik conf powinien być taki.

Otwórz terminal wpisz poniższe polecenia

Strona główna- ls próbka nano.conf Dodaj do niego poniższą treść.
<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName 0.0.0.0
    ServerAlias 0.0.0.0
    DocumentRoot /var/www/html/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    <Directory "/var/www/html/">
            Options Indexes FollowSymLinks
            AllowOverride all
            Require all granted
    </Directory>
</VirtualHost>

Teraz potrzebujesz aby włączyć próbkę.plik conf za pomocą następującego polecenia

cd /etc/apache2/sites-available
sudo a2ensite sample.conf

Następnie poprosi Cię o przeładowanie serwera apache, używając serwis sudo apache2 reload or restart

Następnie otwórz folder localhost / build i dodaj .plik htaccess o treści Poniżej.

   RewriteEngine On
   RewriteBase /
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteCond %{REQUEST_FILENAME} !-l
   RewriteRule ^.*$ / [L,QSA]

Teraz aplikacja działa normalnie.

Uwaga: Zmień 0.0.0.0 IP na lokalny adres IP.

W razie jakichkolwiek wątpliwości prosimy o komentarz.

Mam nadzieję, że to pomoże i inni

 22
Author: Venkatesh Somu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-19 14:12:52

Jeśli używasz Create React App:

Jest świetny spacer o tym problemie z rozwiązaniami dla wielu głównych platform hostingowych, które można znaleźć tutaj na stronie Create React app. Na przykład, używam Reactowego routera v4 i Netlify dla mojego kodu nakładki. Wystarczyło dodać 1 plik do mojego folderu publicznego ("_redirects") i jedną linijkę kodu w tym pliku:

/*  /index.html  200

Teraz moja strona poprawnie renderuje ścieżki jak mysite.com/pricing po wprowadzeniu do przeglądarki lub gdy ktoś naciśnie odśwież.

 20
Author: Colton Hicks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-27 18:55:43

Jeśli hostujesz swoją aplikację react w IIS, po prostu dodaj stronę internetową.plik konfiguracyjny zawierający:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" path="/" responseMode="ExecuteURL" />
    </httpErrors>
  </system.webServer>
</configuration>

Spowoduje to, że serwer IIS zwróci stronę główną klientowi zamiast błędu 404 i nie będzie musiał używać historii skrótów.

 17
Author: Chtiwi Malek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 10:47:16

Serwer Dev Webpack ma opcję, aby to włączyć. Otwórz package.json i dodaj --history-api-fallback. To rozwiązanie zadziałało dla mnie.

React-router-tutorial

 17
Author: sree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-14 07:45:12

Dodaj to do webpack.config.js:

devServer: {
    historyApiFallback: true
}
 14
Author: suraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-26 15:29:08

Stos produkcyjny: React, React Router v4, BrowswerRouter, Express, Nginx

1) przeglądarka użytkowników dla ładnych adresów URL

// app.js

import { BrowserRouter as Router } from 'react-router-dom'

const App = () {
  render() {
    return (
        <Router>
           // your routes here
        </Router>
    )
  }
}

2) Dodaj indeks.html do wszystkich nieznanych żądań za pomocą /*

// server.js

app.get('/*', function(req, res) {   
  res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
    if (err) {
      res.status(500).send(err)
    }
  })
})

3) Pakiet webpack z webpack -p

4) run nodemon server.js or node server.js

Jeśli chcesz, aby nginx zajął się tym w bloku serwerów, zignoruj Krok 2:
location / {
    try_files $uri /index.html;
}
 13
Author: Isaac Pak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-20 03:32:54

Spróbuj dodać ".htaccess " plik w folderze publicznym z poniższym kodem.

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

RewriteRule ^ /index.html [L]  
 7
Author: Kiran Joshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-29 06:26:11

Jeśli masz alternatywę do indeksu.html, upewnij się, że w indeksie.plik html masz to:

<script>
  System.config({ baseURL: '/' });
</script>

Może się to różnić w zależności od projektu.

 6
Author: Matt Goo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-03 00:11:17

Jeśli używasz firebase wszystko, co musisz zrobić, to upewnić się, że masz właściwość przepisuje w swojej firebase.plik json w katalogu głównym aplikacji(w sekcji hosting).

Na przykład:

{ 
  "hosting": {
    "rewrites": [{
      "source":"**",
      "destination": "/index.html"
    }]    
  }
}

Mam nadzieję, że to oszczędzi komuś innego gromadkę frustracji i zmarnowanego czasu.

Szczęśliwego kodowania...

Czytaj dalej w temacie:

Https://firebase.google.com/docs/hosting/full-config#rewrites

Firebase CLI: "Konfiguracja jako jednostronicowa app (przepisz wszystkie adresy URL do / index.html)"

 5
Author: Joshua Dyck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 02:46:49

Znalazłem rozwiązanie dla mojego SPA z reactowym routerem (Apache). Po prostu dodaj .htaccess

<IfModule mod_rewrite.c>

  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]

</IfModule>

Źródło: https://gist.github.com/alexsasharegan/173878f9d67055bfef63449fa7136042

 4
Author: Sasha Ignashevich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-20 22:41:03

Nie używam jeszcze renderowania po stronie serwera, ale trafiłem w ten sam problem, co OP, w którym Link wydawał się działać dobrze przez większość czasu, ale nie powiódł się, gdy miałem parametr. Udokumentuję moje rozwiązanie, żeby sprawdzić, czy komuś pomoże.

Mój główny jsx Zawiera to:

<Route onEnter={requireLogin} path="detail/:id" component={ModelDetail} />

Działa to dobrze dla pierwszego pasującego łącza, ale gdy identyfikator :zmienia się w wyrażeniach <Link> zagnieżdżonych na stronie szczegółów modelu, url zmienia się na pasku przeglądarki, ale zawartość strony początkowo nie zmieniła się na odzwierciedlają połączony model.

Problem polegał na tym, że użyłem props.params.id do Ustawienia modelu w componentDidMount. Komponent jest montowany tylko raz, więc oznacza to, że pierwszy model jest Tym, który przykleja się na stronie, a kolejne linki zmieniają rekwizyty, ale pozostawiają stronę wyglądającą bez zmian.

Ustawienie modelu w stanie komponentu zarówno w componentDidMount, jak i w componentWillReceiveProps (gdzie opiera się na kolejnych właściwościach) rozwiązuje problem, a zawartość strony zmienia się tak, aby odzwierciedlała pożądany model.

 3
Author: Paul Whipp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-18 08:27:24

Ten temat jest trochę stary i rozwiązany, ale chciałbym zaproponować Ci proste, jasne i lepsze rozwiązanie. Działa, jeśli używasz serwera www.

Każdy serwer WWW ma możliwość przekierowania użytkownika na stronę błędu w przypadku http 404. Aby rozwiązać ten problem, musisz przekierować użytkownika na stronę indeksu.

Jeśli korzystasz z Java base server (tomcat lub dowolnego serwera aplikacji java) rozwiązaniem może być "po": {]}

Www.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- WELCOME FILE LIST -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <!-- ERROR PAGES DEFINITION -->
    <error-page>
        <error-code>404</error-code>
        <location>/index.jsp</location>
    </error-page>

</web-app>

Przykład:

  • GET http://example.com/about
  • serwer WWW wyrzuca http 404 ponieważ ta strona nie istnieje po stronie serwera
  • Konfiguracja strony błędu informuje serwer, który wysyła indeks.strona jsp powrót do użytkownika
  • następnie JS wykona resztę zadania po stronie klienta, ponieważ url po stronie klienta jest nadal http://example.com/about .

Że czy to, nie potrzeba więcej magii:)

 3
Author: zappee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 11:43:51

Dla tych, którzy używają IIS 10, to jest to, co powinieneś zrobić, aby to naprawić. Upewnij się, że używasz browserHistory z tym. Co do referencji podam kod do routingu, ale nie to się liczy, liczy się następny krok po kodzie komponentu poniżej:

class App extends Component {
    render() {
        return (
            <Router history={browserHistory}>
                <div>
                    <Root>
                        <Switch>
                            <Route exact path={"/"} component={Home} />    
                            <Route path={"/home"} component={Home} />
                            <Route path={"/createnewproject"} component={CreateNewProject} />
                            <Route path={"/projects"} component={Projects} />
                            <Route path="*" component={NotFoundRoute} />
                        </Switch>
                    </Root>
                </div>
            </Router>
        )
    }
}
render (<App />, window.document.getElementById("app"));

Ponieważ problem polega na tym, że IIS otrzymuje żądanie od przeglądarek klienckich, zinterpretuje adres URL tak, jakby pytał o stronę, a następnie zwraca stronę 404, ponieważ nie ma dostępnej strony. Do the "po": {]}

  1. Otwórz IIS
  2. rozwiń serwer, a następnie otwórz Folder witryny
  3. Kliknij stronę / aplikację
  4. Przejdź do stron błędów
  5. otwórz pozycję statusu błędu 404 na liście
  6. zamiast opcji "Wstaw zawartość ze statycznego pliku do odpowiedzi na błąd", zmień ją na "wykonaj adres URL na tej stronie" i dodaj wartość ukośnika " / " do adresu URL.

I teraz będzie działać dobrze.

Tutaj wpisz opis obrazka Tutaj wpisz opis obrazka

I hope it pomaga. :-)

 3
Author: Martin Lloyd Jose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-29 07:29:49

Jeśli używasz Express lub innego frameworka w backendzie, możesz dodać podobną konfigurację jak poniżej i sprawdzić ścieżkę publiczną Webpack w konfiguracji, powinna działać dobrze nawet przy przeładowaniu, jeśli używasz BrowserRouter

expressApp.get('/*', (request, response) => {
    response.sendFile(path.join(__dirname, '../public/index.html'));
});
 3
Author: neeraj-dixit27,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-15 03:15:30

Naprawiono błąd "nie można pobrać / URL" przy odświeżaniu lub przy bezpośrednim wywołaniu adresu URL.

Skonfiguruj swój webpack.config.js aby się spodziewać podanego łącza trasy takie jak to.

module.exports = {
  entry: './app/index.js',
  output: {
       path: path.join(__dirname, '/bundle'),
       filename: 'index_bundle.js',
       publicPath: '/'
  },
 3
Author: Lalit Tyagi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-15 03:15:59

Możesz spróbować przeczytać to wszystko, choć nie jest moje:

Https://www.andreasreiterer.at/fix-browserrouter-on-apache/

Naprawianie routingu aplikacji Oto, jak w końcu naprawić routing. Aby powiedzieć Apache ' owi, aby przekierował żądania do indeksu.html gdzie mieszka nasza aplikacja, musimy zmodyfikować .plik htaccess. Jeśli nie ma jeszcze takiego pliku w folderze aplikacji, po prostu go Utwórz.

Więc upewnij się, że umieścisz te 4 linie, które w magiczny sposób sprawią, że Twój routing praca.

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

Po tym jak to umieścimy .plik htaccess do tego samego katalogu co indeks.html, Apache przekieruje każde nowe żądanie bezpośrednio do Twojej aplikacji.

Bonus: wdrożenie aplikacji React do podkatalogu

Jeśli wdrażasz swoją aplikację do podkatalogu, więc jest ona dostępna np. przez https://myapp.com/the-app , wkrótce zauważysz, że jest inny problem. Każde kliknięcie na nową trasę spowoduje przekształcenie adresu URL w coś w rodzaju https://myapp.com/route-abc - który pęknie ponownie po przeładowaniu. Ale jest na to prosta poprawka:

BrowserRouter ma właściwość o nazwie basename, w której możesz określić ścieżkę podkatalogu:

Od teraz, każda trasa jak / kontakty spowoduje URL jak http://myapp.com/the-app/contacts .

 3
Author: Rishabh Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-23 16:51:11

Jeśli używasz polecenia "create-react-app",

Aby wygenerować aplikację reactową, następnie pakiet.json musi mieć jedną zmianę, aby poprawnie uruchomić production build react SPA w przeglądarce. Otwórz paczkę.json i dodaj do tego następujący segment kodu,

"start": "webpack-dev-server --inline --content-base . --history-api-fallback"

Tutaj najważniejszą częścią jest "--history-api-fallback", aby włączyć oddzwanianie do API historii.

Czasami pojawi się błąd 404, jeśli używasz Springa lub innego back-endowego API. Więc w takiej sytuacji, ty musisz mieć kontroler w back-endzie, aby przesłać dowolne żądanie (pożądane) do indeksu.plik html do obsługi przez react-router. Poniżej przedstawiono przykładowy kontroler napisany przy użyciu springa.

@Controller
public class ForwardingController {
    @RequestMapping("/<any end point name>/{path:[^\\.]+}/**")
    public String forward(HttpServletRequest httpServletRequest) {
        return "forward:/";
    }
}

Na przykład, jeśli weźmiemy back-end API REST endpoint jako " abc " (http://localhost:8080/abc/**) każde żądanie przychodzące do tego punktu końcowego przekieruje do aplikacji reactowej (index.plik html), a react-router poradzi sobie z tym po słowach.

 3
Author: Malinda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-16 00:17:45

Ponieważ używam. Net Core MVC coś takiego mi pomogło:

    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            var url = Request.Path + Request.QueryString;
            return App(url);
        }

        [Route("App")]
        public IActionResult App(string url)
        {
            return View("/wwwroot/app/build/index.html");
        }
   }

Zasadniczo po stronie MVC, wszystkie Nie pasujące trasy spadną do Home/Index, Jak określono w startup.cs. Wewnątrz Index możliwe jest uzyskanie oryginalnego adresu URL żądania i przekazanie go w razie potrzeby.

Startup.cs

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });
 2
Author: Elnoor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-11 04:41:36

Jeśli hostujesz w IIS; dodanie tego do mojego webconfig rozwiązało mój problem

<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
    <remove statusCode="500" subStatusCode="100" />
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="404" subStatusCode="-1" />
    <error statusCode="404" path="/" responseMode="ExecuteURL" />
    <error statusCode="500" prefixLanguageFilePath="" path="/error_500.asp" responseMode="ExecuteURL" />
    <error statusCode="500" subStatusCode="100" path="/error_500.asp" responseMode="ExecuteURL" />
</httpErrors>

Możesz zrobić podobną konfigurację dla każdego innego serwera

 2
Author: Barny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-15 03:15:13

Użycie HashRouter zadziałało u mnie z Redux również, po prostu zamień:

import {
  Router //replace Router
} from "react-router-dom";

ReactDOM.render(
    <LocaleProvider locale={enUS}>
    <Provider store={Store}>
        <Router history={history}> //replace here saying Router
            <Layout/>
        </Router>
    </Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();

Do:

import {
  HashRouter //replaced with HashRouter
} from "react-router-dom";

ReactDOM.render(
    <LocaleProvider locale={enUS}>
    <Provider store={Store}>
        <HashRouter history={history}> //replaced with HashRouter
            <Layout/>
        </HashRouter>
    </Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();
 2
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-24 14:09:14

Na wszelki wypadek, ktoś tu szuka rozwiązania na React JS SPA z Laravel. Przyjęta odpowiedź jest najlepszym wyjaśnieniem, dlaczego takie problemy się zdarzają. Jak już wyjaśniono, musisz skonfigurować zarówno po stronie klienta, jak i po stronie serwera. W szablonie blade Dołącz plik dołączony do js, upewnij się, że używasz URL facade w ten sposób

<script src="{{ URL::to('js/user/spa.js') }}"></script>

W swoich trasach upewnij się, że dodajesz to do głównego punktu końcowego, w którym znajduje się szablon blade. Na przykład,

Route::get('/setting-alerts', function () {
   return view('user.set-alerts');
});

Powyższe jest głównym punktem końcowym dla szablon ostrza. Teraz dodaj też opcjonalną trasę,

Route::get('/setting-alerts/{spa?}', function () {
  return view('user.set-alerts');
});

Problem polega na tym, że najpierw ładowany jest szablon blade, a następnie Router reactowy. Tak więc, kiedy ładujesz '/setting-alerts', ładuje html i js. Ale po załadowaniu '/setting-alerts/about', najpierw ładuje się po stronie serwera. Ponieważ po stronie serwera nie ma nic w tej lokalizacji, zwraca not found. Gdy masz ten opcjonalny router, ładuje tę samą stronę i react router jest również ładowany, a następnie react loader decyduje, który komponent do pokazania. Mam nadzieję, że to pomoże.

 1
Author: Koushik Das,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-14 03:23:55

Dodanie więcej informacji do Joshua Dyck ' s answer .

Jeśli używasz Firebase i chcesz używać zarówno trasy głównej, jak i trasy podkatalogów, musisz dodać następujący kod w firebase.json:

{
  "hosting": {
    "rewrites": [
      {
        "source": "*",
        "destination": "/index.html"
      },
      {
        "source": "/subdirectory/**",
        "destination": "/subdirectory/index.html"
      }
    ]
  }
}

Przykład:

Budujesz stronę internetową dla klienta. Chcesz, aby właściciel strony dodawał informacje w https://your.domain.com/management podczas gdy użytkownicy Strony będą nawigować do https://your.domain.com .

W tym przypadek Twój plik firebase.json będzie wyglądał tak:

{
  "hosting": {
    "rewrites": [
      {
        "source": "*",
        "destination": "/index.html"
      },
      {
        "source": "/management/**",
        "destination": "/management/index.html"
      }
    ]
  }
}
 1
Author: neomib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-16 17:15:07