J'utilise React-router et cela fonctionne bien lorsque je clique sur les boutons de lien, mais lorsque je rafraîchis ma page Web, il ne charge pas ce que je veux.
Par exemple, je suis localhost/joblist
dedans et tout va bien parce que je suis arrivé ici en appuyant sur un lien. Mais si je rafraîchis la page Web, j'obtiens:
Cannot GET /joblist
Par défaut, cela ne fonctionnait pas comme ça. Au départ, j'avais mon URL au fur localhost/#/
et à mesure localhost/#/joblist
et elles fonctionnaient parfaitement bien. Mais je n'aime pas ce type d'URL, alors en essayant de l'effacer #
, j'ai écrit:
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
Ce problème ne se produit pas avec localhost/
, celui-ci renvoie toujours ce que je veux.
EDIT: Cette application est d'une seule page, donc /joblist
n'a pas besoin de demander quoi que ce soit à n'importe quel serveur.
EDIT2: Mon routeur entier.
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);
});
la source
#
symbole? Je vous remercie!index.html
. Cela vous assurera d'êtreindex.html
touché quoi qu'il arrive.Réponses:
En regardant les commentaires sur la réponse acceptée et la nature générique de cette question («ne fonctionne pas»), j'ai pensé que cela pourrait être un bon endroit pour quelques explications générales sur les problèmes impliqués ici. Cette réponse est donc conçue comme une information / élaboration de base sur le cas d'utilisation spécifique de l'OP. S'il vous plaît, supportez-moi.
Côté serveur vs côté client
La première chose importante à comprendre à ce sujet est qu'il y a maintenant 2 endroits où l'URL est interprétée, alors qu'il n'y en avait qu'un dans «l'ancien temps». Dans le passé, lorsque la vie était simple, certains utilisateurs envoyaient une demande
http://example.com/about
au serveur, qui inspectait la partie chemin de l'URL, déterminait que l'utilisateur demandait la page à propos, puis renvoyait cette page.Avec le routage côté client, ce que fournit React-Router, les choses sont moins simples. Au début, le client n'a pas encore de code JS chargé. Ainsi, la toute première demande sera toujours adressée au serveur. Cela retournera alors une page qui contient les balises de script nécessaires pour charger React et React Router, etc. Ce n'est que lorsque ces scripts ont été chargés que la phase 2 démarre. Dans la phase 2, lorsque l'utilisateur clique sur le lien de navigation `` A propos de nous '' par exemple, l'URL est modifiée localement uniquement en
http://example.com/about
(rendue possible par l' API Historique ), mais aucune demande au serveur n'est faite. Au lieu de cela, React Router fait son travail côté client, détermine la vue React à restituer et la restitue. En supposant que votre page À propos n'a pas besoin d'appeler REST, c'est déjà fait. Vous êtes passé de Home à About Us sans qu'aucune demande de serveur n'ait été déclenchée.Donc, fondamentalement, lorsque vous cliquez sur un lien, certaines exécutions Javascript manipulent l'URL dans la barre d'adresse, sans provoquer d'actualisation de la page , ce qui entraîne à son tour React Router à effectuer une transition de page côté client .
Mais considérez maintenant ce qui se passe si vous copiez-collez l'URL dans la barre d'adresse et l'envoyez par e-mail à un ami. Votre ami n'a pas encore chargé votre site Web. En d'autres termes, elle est toujours en phase 1 . Aucun React Router n'est encore en cours d'exécution sur sa machine. Son navigateur va donc faire une demande au serveur
http://example.com/about
.Et c'est là que commence votre problème. Jusqu'à présent, vous pouviez vous en sortir en plaçant simplement un code HTML statique à la racine Web de votre serveur. Mais cela donnerait des
404
erreurs pour toutes les autres URL à la demande du serveur . Ces mêmes URL fonctionnent très bien côté client , car React Router effectue le routage pour vous, mais elles échouent côté serveur, sauf si vous les faites comprendre à votre serveur.Combinaison du routage côté serveur et côté client
Si vous souhaitez que l'
http://example.com/about
URL fonctionne à la fois côté serveur et côté client, vous devez configurer des itinéraires pour celle-ci à la fois côté serveur et côté client. Est-ce logique, non?Et c'est là que vos choix commencent. Les solutions vont du contournement complet du problème, via une route fourre-tout qui renvoie le HTML d'amorçage, à l'approche isomorphe complète où le serveur et le client exécutent le même code JS.
.
Contourner complètement le problème: Hash History
Avec l' historique de hachage au lieu de l' historique du navigateur , votre URL pour la page à propos ressemblerait à ceci:
http://example.com/#/about
La partie après le#
symbole hash ( ) n'est pas envoyée au serveur. Ainsi, le serveur ne voithttp://example.com/
et n'envoie que la page d'index comme prévu. React-Router ramassera la#/about
pièce et affichera la bonne page.Inconvénients :
.
Fourre-tout
Avec cette approche vous utilisez l' historique du navigateur, mais juste mettre en place un fourre-tout sur le serveur qui envoie
/*
àindex.html
, vous donnant effectivement la même situation avec Hash Histoire. Cependant, vous avez des URL propres et vous pouvez améliorer ce schéma plus tard sans avoir à invalider tous les favoris de vos utilisateurs.Inconvénients :
.
Hybride
Dans l'approche hybride, vous développez le scénario fourre-tout en ajoutant des scripts spécifiques pour des itinéraires spécifiques. Vous pouvez créer des scripts PHP simples pour renvoyer les pages les plus importantes de votre site avec du contenu inclus, afin que Googlebot puisse au moins voir ce qu'il y a sur votre page.
Inconvénients :
.
Isomorphe
Et si nous utilisons Node JS comme serveur pour pouvoir exécuter le même code JS aux deux extrémités? Maintenant, nous avons tous nos itinéraires définis dans une seule configuration de routeur de réaction et nous n'avons pas besoin de dupliquer notre code de rendu. C'est pour ainsi dire «le Saint Graal». Le serveur envoie exactement le même balisage que celui auquel nous nous retrouverions si la transition de page s'était produite sur le client. Cette solution est optimale en termes de référencement.
Inconvénients :
window
côté serveur, etc.).
Que dois-je utiliser?
Choisissez celui avec lequel vous pouvez vous en sortir. Personnellement, je pense que le fourre-tout est assez simple à mettre en place, ce serait donc mon minimum. Cette configuration vous permet d'améliorer les choses au fil du temps. Si vous utilisez déjà Node JS comme plate-forme de serveur, j'envisagerais certainement de faire une application isomorphe. Oui, c'est difficile au début, mais une fois que vous avez compris, c'est en fait une solution très élégante au problème.
Donc, fondamentalement, pour moi, ce serait le facteur décisif. Si mon serveur fonctionne sur Node JS, je deviendrais isomorphe; Sinon, j'opterais pour la solution Catch-all et je développerais simplement celle-ci (solution hybride) au fur et à mesure que le temps et les exigences SEO l'exigent.
Si vous souhaitez en savoir plus sur le rendu isomorphe (également appelé «universel») avec React, il existe de bons tutoriels sur le sujet:
Aussi, pour commencer, je vous recommande de regarder quelques kits de démarrage. Choisissez-en un qui correspond à vos choix pour la pile technologique (rappelez-vous, React n'est que le V dans MVC, vous avez besoin de plus de choses pour créer une application complète). Commencez par regarder celui publié par Facebook lui-même:
Ou choisissez l'un des nombreux par la communauté. Il y a maintenant un joli site qui essaie de les indexer tous:
J'ai commencé avec ceux-ci:
Actuellement, j'utilise une version maison de brassage universel qui a été inspirée par les deux kits de démarrage ci-dessus, mais ils sont désormais obsolètes.
Bonne chance dans ta quête!
la source
/*
et faites-le répondre avec votre page HTML. La chose délicate ici est de vous assurer que vous n'interceptez pas les demandes pour les fichiers .js et .css avec cette route.createMemoryHistory is not a function
erreur. Ça te regarde? stackoverflow.com/questions/45002573/…Les réponses ici sont toutes extrêmement utiles, ce qui a fonctionné pour moi a été de configurer mon serveur Webpack pour attendre les itinéraires.
L'historiqueApiFallback est ce qui a résolu ce problème pour moi. Maintenant, le routage fonctionne correctement et je peux rafraîchir la page ou saisir directement l'URL. Pas besoin de vous soucier des solutions de contournement sur votre serveur de noeud. Cette réponse ne fonctionne évidemment que si vous utilisez webpack.
EDIT: voir ma réponse ici pour une raison plus détaillée pour laquelle cela est nécessaire: https://stackoverflow.com/a/37622953/5217568
la source
historyApiFallback
est suffisant. Comme pour toutes les autres options, il peut également être défini à partir de CLI avec le drapeau--history-api-fallback
.Vous pouvez modifier votre
.htaccess
fichier et insérer ceci:j'utilise
react: "^16.12.0"
etreact-router: "^5.1.2"
cette méthode est le fourre-tout et est probablement le moyen le plus simple de vous aider à démarrer.la source
Pour React Router V4 :
Si vous essayez de résoudre ce problème par la technique de Hash History mentionnée dans d'autres réponses, notez que
ne fonctionne pas en V4, veuillez utiliser à la
HashRouter
place:Référence: HashRouter
la source
Le routeur peut être appelé de deux manières différentes, selon que la navigation s'effectue sur le client ou sur le serveur. Vous l'avez configuré pour un fonctionnement côté client. Le paramètre clé est le deuxième de la méthode d'exécution , l'emplacement.
Lorsque vous utilisez le composant React Router Link, il bloque la navigation du navigateur et appelle transitionTo pour effectuer une navigation côté client. Vous utilisez HistoryLocation, il utilise donc l'API d'historique HTML5 pour compléter l'illusion de navigation en simulant la nouvelle URL dans la barre d'adresse. Si vous utilisez des navigateurs plus anciens, cela ne fonctionnera pas. Vous devez utiliser le composant HashLocation.
Lorsque vous appuyez sur Actualiser, vous contournez tout le code React et React Router. Le serveur reçoit la demande
/joblist
et doit renvoyer quelque chose. Sur le serveur, vous devez transmettre le chemin d'accès qui a été demandé à larun
méthode pour qu'elle affiche la vue correcte. Vous pouvez utiliser la même carte d'itinéraire, mais vous aurez probablement besoin d'un appel différent versRouter.run
. Comme le souligne Charles, vous pouvez utiliser la réécriture d'URL pour gérer cela. Une autre option consiste à utiliser un serveur node.js pour gérer toutes les demandes et transmettre la valeur du chemin d'accès comme argument d'emplacement.En express, par exemple, cela pourrait ressembler à ceci:
Notez que le chemin de demande est transmis à
run
. Pour ce faire, vous devez disposer d'un moteur de vue côté serveur auquel vous pouvez transmettre le code HTML rendu. Il existe un certain nombre d'autres considérations lors de l'utilisationrenderToString
et de l'exécution de React sur le serveur. Une fois que la page est rendue sur le serveur, lorsque votre application se charge dans le client, elle s'affichera à nouveau, mettant à jour le HTML rendu côté serveur selon les besoins.la source
Dans votre index.html
head
, ajoutez ce qui suit:Ensuite, lors de l'exécution avec le serveur de développement webpack, utilisez cette commande.
--history-api-fallback
est la partie importantela source
/
alorsHashRouter
ne fonctionnera pas (si vous utilisez le routage hachage)J'ai utilisé create-react-app pour créer un site Web tout à l'heure et j'ai présenté le même problème ici. J'utilise
BrowserRouting
dureact-router-dom
paquet. Je suis en cours d'exécution sur un serveur Nginx et ce qui a résolu pour moi l'ajout de ce qui suit à/etc/nginx/yourconfig.conf
Ce qui correspond à l'ajout de ce qui suit au
.htaccess
cas où vous exécutez AppacheCela semble également être la solution suggérée par Facebook eux-mêmes et peut être trouvée ici
la source
Cela peut résoudre votre problème
J'ai également rencontré le même problème dans l'application ReactJS en mode Production. Voici la 2 solution au problème.
1.Changez l'historique de routage en "hashHistory" au lieu de browserHistory à la place de
Maintenant, créez l'application en utilisant la commande
Ensuite, placez le dossier de construction dans votre dossier var / www /, Maintenant, l'application fonctionne correctement avec l'ajout de la balise # dans chaque URL. comme
localhost / # / home localhost / # / aboutus
Solution 2: sans balise # à l'aide de browserHistory,
Définissez votre historique = {browserHistory} dans votre routeur, maintenant construisez-le en utilisant sudo npm run build.
Vous devez créer le fichier "conf" pour résoudre la page 404 introuvable, le fichier conf devrait être comme ceci.
ouvrez votre terminal tapez les commandes ci-dessous
cd / etc / apache2 / sites-available ls nano sample.conf Ajoutez-y le contenu ci-dessous.
Vous devez maintenant activer le fichier sample.conf à l'aide de la commande suivante
puis il vous demandera de recharger le serveur apache, en utilisant sudo service apache2 reload or restart
puis ouvrez votre dossier localhost / build et ajoutez le fichier .htaccess avec le contenu ci-dessous.
Maintenant, l'application fonctionne normalement.
Remarque: remplacez 0.0.0.0 ip par votre adresse ip locale.
En cas de doute à ce sujet, n'hésitez pas à formuler un commentaire.
J'espère que cela sera utile aux autres.
la source
"react-router-dom": "^5.1.2"
t-elle?, J'utilise<BrowserRouter>
Si vous hébergez une application React via AWS Static S3 Hosting & CloudFront
Ce problème s'est présenté par CloudFront en répondant avec un message 403 Access Denied car il s'attendait à ce que / some / other / path existe dans mon dossier S3, mais ce chemin n'existe qu'en interne dans le routage de React avec react-router.
La solution était de mettre en place une règle de distribution des pages d'erreur. Accédez aux paramètres CloudFront et choisissez votre distribution. Allez ensuite dans l'onglet "Pages d'erreur". Cliquez sur "Créer une réponse d'erreur personnalisée" et ajoutez une entrée pour 403 car c'est le code d'état d'erreur que nous obtenons. Définissez le chemin de la page de réponse sur /index.html et le code d'état sur 200. Le résultat final m'étonne par sa simplicité. La page d'index est servie, mais l'URL est conservée dans le navigateur, donc une fois que l'application React se charge, elle détecte le chemin de l'URL et navigue vers l'itinéraire souhaité.
Pages d'erreur 403 règle
la source
Le serveur de développement Webpack a une option pour l'activer. Ouvrez
package.json
et ajoutez--history-api-fallback
. Ces solutions ont fonctionné pour moi.réagir-routeur-tutoriel
la source
webpack-dev-server
mais comment puis-je résoudre ce problème pour la génération de production?Si vous hébergez votre application React sur IIS, ajoutez simplement un fichier web.config contenant:
Cela indiquera au serveur IIS de renvoyer la page principale au client au lieu d'une erreur 404 et pas besoin d'utiliser l'historique de hachage.
la source
Ajoutez ceci à
webpack.config.js
:la source
Pile de production: React, React Router v4, BrowswerRouter, Express, Nginx
1) User BrowserRouter pour de jolies URL
2) Ajoutez index.html à toutes les demandes inconnues en utilisant
/*
3) bundle webpack avec
webpack -p
4) exécuter
nodemon server.js
ounode server.js
EDIT: vous souhaiterez peut-être laisser nginx gérer cela dans le bloc serveur et ignorer l'étape 2:
la source
import path from 'path
ouconst path = require('path')
/*
) vient de me sauver la journée. Je vous remercie! :)Si vous utilisez l'application Create React:
Il y a cependant une bonne marche à suivre pour résoudre ce problème avec des solutions pour de nombreuses plates-formes d'hébergement majeures que vous pouvez trouver ICI sur la page de l'application Create React. Par exemple, j'utilise React Router v4 et Netlify pour mon code frontal. Tout ce qu'il a fallu a été d'ajouter 1 fichier à mon dossier public ("_redirects") et une ligne de code dans ce fichier:
Maintenant, mon site Web affiche correctement des chemins tels que mysite.com/pricing lorsqu'il est entré dans le navigateur ou lorsque quelqu'un frappe actualiser.
la source
Essayez d'ajouter le fichier ".htaccess" dans le dossier public avec le code ci-dessous.
la source
Si vous avez un repli sur votre index.html, assurez-vous que dans votre fichier index.html vous avez ceci:
Cela peut différer d'un projet à l'autre.
la source
head
: <base href = "/">Si vous utilisez Firebase, tout ce que vous avez à faire est de vous assurer que vous avez une propriété de réécriture dans votre fichier firebase.json à la racine de votre application (dans la section hébergement).
Par exemple:
J'espère que cela fera économiser à quelqu'un d'autre un trésor de frustration et de perte de temps.
Bon codage ...
Pour en savoir plus sur le sujet:
https://firebase.google.com/docs/hosting/full-config#rewrites
Firebase CLI: "Configurer comme une application d'une seule page (réécrire toutes les URL dans /index.html)"
la source
J'ai trouvé la solution pour mon SPA avec un routeur React (Apache). Ajoutez simplement .htaccess
source: https://gist.github.com/alexsasharegan/173878f9d67055bfef63449fa7136042
la source
Je n'utilise pas encore le rendu côté serveur mais j'ai rencontré le même problème que l'OP où Link semblait bien fonctionner la plupart du temps mais a échoué lorsque j'avais un paramètre. Je vais documenter ma solution ici pour voir si elle aide quelqu'un.
Mon jsx principal contient ceci:
Cela fonctionne bien pour le premier lien correspondant, mais lorsque: id change dans
<Link>
expressions imbriquées sur la page de détails de ce modèle, l'url change dans la barre de navigateur, mais le contenu de la page n'a pas initialement changé pour refléter le modèle lié.Le problème était que j'avais utilisé le
props.params.id
pour définir le modèlecomponentDidMount
. Le composant n'est monté qu'une seule fois, ce qui signifie que le premier modèle est celui qui reste sur la page et les liens suivants modifient les accessoires mais laissent la page inchangée.La définition du modèle dans l'état du composant à la fois
componentDidMount
et danscomponentWillReceiveProps
(où il est basé sur les accessoires suivants) résout le problème et le contenu de la page change pour refléter le modèle souhaité.la source
props
) isocomponentDidMount
si vous souhaitez essayer le rendu côté serveur. ParcecomponentDidMount
que n'est appelé que dans le navigateur. Son but est de faire des choses avec le DOM, comme attacher des écouteurs d'événements àbody
etc. que vous ne pouvez pas fairerender
.Ce sujet est un peu ancien et résolu mais je voudrais vous proposer une solution simple, claire et meilleure. Cela fonctionne si vous utilisez un serveur Web.
Chaque serveur Web a la possibilité de rediriger l'utilisateur vers une page d'erreur dans le cas de http 404. Pour résoudre ce problème, vous devez rediriger l'utilisateur vers la page d'index.
Si vous utilisez un serveur de base Java (tomcat ou tout autre serveur d'applications Java), la solution pourrait être la suivante:
web.xml:
Exemple:
Ça y est, plus besoin de magie :)
la source
const browserHistory = useRouterHistory(createHistory)({ basename: '/<appname>' });
Si vous utilisez Express ou un autre framework dans le backend, vous pouvez ajouter la configuration similaire comme ci-dessous et vérifier le chemin public Webpack dans la configuration, cela devrait fonctionner correctement même lors du rechargement si vous utilisez BrowserRouter
la source
Correction de l'erreur "ne peut pas obtenir / URL" lors de l'actualisation ou lors de l'appel direct de l'URL.
Configurez votre webpack.config.js pour attendre le lien donné les itinéraires comme celui-ci.
la source
Comme j'utilise .Net Core MVC, quelque chose comme ça m'a aidé:
Fondamentalement, du côté MVC, toutes les routes qui ne correspondent pas tomberont
Home/Index
comme indiqué dansstartup.cs
. À l'intérieur,Index
il est possible d'obtenir l'URL de demande d'origine et de la transmettre où vous en avez besoin.la source
Si vous hébergez dans IIS; L'ajout de ceci à ma configuration Web a résolu mon problème
Vous pouvez effectuer une configuration similaire pour tout autre serveur
la source
Au cas où quelqu'un chercherait une solution sur React JS SPA avec Laravel. La réponse acceptée est la meilleure explication de la raison pour laquelle de tels problèmes se produisent. Comme déjà expliqué, vous devez configurer à la fois côté client et côté serveur. Dans votre modèle de lame, incluez le fichier js fourni, assurez-vous de l'utiliser
URL facade
comme ceciDans vos itinéraires, assurez-vous de l'ajouter au point de terminaison principal où se trouve le modèle de lame. Par exemple,
Ce qui précède est le principal critère d'évaluation du modèle de lame. Maintenant, ajoutez également un itinéraire facultatif,
Le problème qui se produit est que le modèle de lame est d'abord chargé, puis le routeur React. Ainsi, lorsque vous chargez
'/setting-alerts'
, il charge le html et le js. Mais lorsque vous chargez'/setting-alerts/about'
, il se charge d'abord côté serveur. Du côté serveur, il n'y a rien sur cet emplacement, il retourne non trouvé. Lorsque vous avez ce routeur en option, il charge la même page et le routeur React est également chargé, puis React Loader décide du composant à afficher. J'espère que cela t'aides.la source
/user/{userID}
, j'ai juste besoin de retourner une/user
vue HTML universelle , d'apporter l'ID et de l'appeler en utilisant AJAX ou axios. Est-il possible de faire ça? sont-ils compatibles avec le référencement?Pour ceux qui utilisent IIS 10, voici ce que vous devez faire pour corriger ce problème. Assurez-vous que vous utilisez browserHistory avec cela. En ce qui concerne la référence, je donnerai le code pour le routage, mais ce n'est pas ce qui compte, ce qui compte c'est la prochaine étape après le code composant ci-dessous:
Étant donné que le problème est qu'IIS reçoit une demande des navigateurs clients, il interprète l'URL comme s'il demandait une page, puis renvoie une page 404 car il n'y a pas de page disponible. Procédez comme suit:
Et cela fonctionnera désormais correctement.
J'espère que ça aide. :-)
la source
J'utilise WebPack, j'ai eu le même problème Solution => Dans votre fichier server.js
Pourquoi mon application ne s'affiche-t-elle pas après avoir été actualisée?
la source
L'utilisation
HashRouter
de Redux a également fonctionné pour moi , il suffit de remplacer simplement:à:
la source
J'ai eu ce même problème et cela solution a fonctionné pour nous ..
Contexte:
Nous hébergeons plusieurs applications sur le même serveur. Quand nous rafraîchirions le serveur ne comprendrait pas où chercher notre index dans le dossier dist pour cette application particulière. Le lien ci-dessus vous mènera à ce qui a fonctionné pour nous ... J'espère que cela vous aidera, car nous avons passé pas mal d'heures à trouver une solution à nos besoins.
Nous utilisons:
mon webpack.config.js
mon index.js
mon app.js
la source
J'aime cette façon de le gérer. Essayez d'ajouter: yourSPAPageRoute / * côté serveur pour vous débarrasser de ce problème.
J'ai choisi cette approche car même l'API native HTML5 History ne prend pas en charge la redirection correcte lors de l'actualisation de la page (pour autant que je sache).
Remarque: la réponse sélectionnée a déjà répondu à cela, mais j'essaie d'être plus précis.
Route express
Testé et je voulais juste partager cela.
J'espère que cela aide.
la source