web-dev-qa-db-fra.com

Les URL de React-routeur ne fonctionnent pas lors de l'actualisation ou de l'écriture manuelle

J'utilise React-router et cela fonctionne bien lorsque je clique sur les boutons de lien, mais lorsque j'actualise ma page Web, il ne charge pas ce que je veux.

Par exemple, je suis dans localhost/joblist et tout va bien parce que je suis arrivé ici en appuyant sur un lien. Mais si j'actualise la page Web, je reçois: Impossible d'obtenir/joblist

Par défaut, ça ne marchait pas comme ça. Initialement, j'avais mon URL: localhost/#/et localhost/#/joblist et ils fonctionnaient parfaitement. Mais je n'aime pas ce genre d'URL, alors j'essayais d'effacer ce '#'.

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

Ce problème ne se produit pas avec localhost /, celui-ci retourne toujours ce que je veux.

EDIT: Cette application est une page unique, 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);
});
407
DavidDev

Les réponses ici sont toutes extrêmement utiles. Ce qui a bien fonctionné pour moi, c’est de configurer mon serveur Webpack pour qu’il attende les itinéraires.

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

HistoryApiFallback est ce qui a résolu ce problème pour moi. Maintenant, le routage fonctionne correctement et je peux actualiser la page ou taper directement l'URL. Pas besoin de s'inquiéter des solutions de rechange 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 pourquoi cela est nécessaire: https://stackoverflow.com/a/37622953/5217568

84
jmancherje

Pour les utilisateurs de React Router V4:

Si vous essayez de résoudre ce problème par la technique d’historique de hachage mentionnée dans d’autres réponses, notez que 

<Router history={hashHistory} >

ne fonctionne pas en V4, utilisez plutôt HashRouter:

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

<HashRouter>
  <App/>
</HashRouter>

Référence: https://reacttraining.com/react-router/web/api/HashRouter

38
user2875289

Vous pouvez changer votre htaccess et insérer ceci:

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

J'utilise react: "^15.3.2", react-router: "^3.0.0", history: "^4.3.0",

38
BrahimS

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 second à la méthode run , 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 cliquez sur Actualiser, vous ignorez tout le code du routeur React et React. Le serveur reçoit la demande pour /joblist et il doit renvoyer quelque chose. Sur le serveur, vous devez transmettre le chemin demandé à la méthode run afin que celle-ci rende la vue correcte. Vous pouvez utiliser la même carte de route, mais vous aurez probablement besoin d'un appel différent pour Router.run. Comme Charles le fait remarquer, 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 en tant qu'argument d'emplacement. 

En express, par exemple, cela pourrait ressembler à ceci:

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 });
    });
});

Notez que le chemin d'accès à la requête 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. renderToString et l'exécution de React sur le serveur soulèvent un certain nombre d'autres considérations. Une fois que la page est restituée sur le serveur, lorsque votre application est chargée dans le client, elle est rendue à nouveau, en mettant à jour le code HTML rendu côté serveur, si nécessaire.

25
Todd

Dans votre index.html head, ajoutez ce qui suit:

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

Ensuite, lors de l'exécution avec webpack dev server, utilisez cette commande.

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

--history-api-fallback est la partie importante

16
Efe Ariaroo

Webpack Dev Server a une option pour l'activer. Ouvrez package.json et ajoutez --history-api-fallback. Cette solution a fonctionné pour moi.

https://github.com/reactjs/react-router-tutorial/tree/master/lessons/10-clean-urls#configuring-votre-serveur

14
srijishks

Si vous hébergez une application de réaction via AWS Static S3 Hosting & CloudFront

Ce problème s’est présenté lorsque CloudFront a répondu avec un message 403 Access Denied car il s’attendait à ce que le répertoire/une/une/une/un autre existe dans mon dossier S3. 

La solution consistait à configurer une règle de distribution des pages d'erreur. Accédez aux paramètres CloudFront et choisissez votre distribution. Ensuite, allez 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 de statut 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. Ainsi, une fois que l'application de réaction est chargée, elle détecte le chemin de l'URL et navigue vers l'itinéraire souhaité. 

Erreur Pages 403 Rule

11
th3morg

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 solution au problème.

1.Changez l'historique de routage en "hashHistory" au lieu de browserHistory à la place de 

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

Maintenant, construisez l'application en utilisant la commande 

Sudo npm run build

Ensuite, placez le dossier de construction dans votre dossier var/www /. Maintenant, l’application fonctionne correctement avec l’ajout du tag # dans chaque URL. comme 

localhost/#/home localhost/#/aboutus

Solution 2: sans balise # en utilisant browserHistory,

Définissez votre historique = {browserHistory} dans votre routeur. Générez-le maintenant en utilisant Sudo npm run build.

Vous devez créer le fichier "conf" pour résoudre la page 404 non trouvée. Le fichier conf devrait ressembler à ceci.

ouvrez votre terminal tapez les commandes ci-dessous 

cd /etc/Apache2/sites-availablelsnano sample.conf Ajoutez-y le contenu ci-dessous.

 <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>

Maintenant, vous devez activer le fichier sample.conf en utilisant la commande suivante

cd /etc/Apache2/sites-available
Sudo a2ensite sample.conf

il vous demandera ensuite de recharger le serveur Apache, en utilisant Service Sudo Apache2 recharger ou redémarrer

puis ouvrez votre dossier localhost/build et ajoutez le fichier .htaccess avec le contenu de ci-dessous.

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

Maintenant, l'application fonctionne normalement.

Remarque: changez 0.0.0.0 ip en votre adresse ip locale.

Si vous avez des doutes à ce sujet, n'hésitez pas à formuler un commentaire.

J'espère que cela aidera les autres.

11
Venkatesh Somu

J'ai utilisé create-react-app pour créer un site Web tout à l'heure et le même problème a été présenté ici. J'utilise BrowserRouting à partir du package react-router-dom. J'exécute sur un serveur Nginx et ce qui l'a résolu pour moi a été d'ajouter ce qui suit à /etc/nginx/yourconfig.conf

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

Ce qui correspond à l'ajout de ce qui suit au .htaccess dans le cas où vous exécutez Appache

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

Cela semble aussi être la solution proposée par Facebook elle-même et peut être trouvée ici

10
Aidin

ajoutez ceci à webpack.config.js

devServer: {
      historyApiFallback: true
  }
8
suraj

Pile de production: React, React Router v4, BrowswerRouter, Express, Nginx

1) User BrowserRouter pour les jolies URL 

// app.js

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

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

2) Ajoutez index.html à toutes les demandes inconnues en utilisant /*

// 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) bundle webpack avec webpack -p

4) exécuter nodemon server.js ou node server.js

EDIT: Vous pouvez laisser nginx gérer cela dans le bloc serveur et ignorer l’étape 2:

location / {
    try_files $uri /index.html;
}
7
Isaac Pak

Essayez d'ajouter le fichier ".htaccess" dans le dossier public avec le code ci-dessous.

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

RewriteRule ^ /index.html [L]  
6
Kiran Joshi

Si vous utilisez l'application Create React:

Il existe une bonne solution à ce problème avec des solutions pour de nombreuses grandes plateformes d'hébergement que vous pouvez trouver ICI sur la page Créer une application React. Par exemple, j'utilise React Router v4 et Netlify pour mon code frontal. Il suffisait d'ajouter 1 fichier à mon dossier public ("_redirects") et une ligne de code dans ce fichier:

/*  /index.html  200

Maintenant, mon site Web affiche correctement les chemins tels que mysite.com/pricing lors de la saisie dans le navigateur ou lorsque quelqu'un clique sur l'actualisation.

4
Colton Hicks

Si vous avez un repli sur votre index.html, assurez-vous que votre fichier index.html contient:

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

Cela peut différer d'un projet à l'autre.

2
Matt Goo

Si vous hébergez votre application de réaction sur IIS, ajoutez simplement un fichier web.config contenant:

<?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>

Cela indiquera à IIS serveur de renvoyer la page principale au client au lieu de l'erreur 404 et inutile d'utiliser l'historique de hachage.

2
Chtiwi Malek

Je n'utilise pas encore le rendu côté serveur mais je rencontre le même problème que l'OP où Link semblait fonctionner correctement la plupart du temps, mais échouait lorsque j'avais un paramètre. Je vais documenter ma solution ici pour voir si cela aide quelqu'un.

Mon principal jsx contient ceci:

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

Cela fonctionne bien pour le premier lien correspondant, mais lorsque l'ID: id change dans les expressions <Link> imbriquées dans la page de détail de ce modèle, l'URL change dans la barre de navigation, 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èle dans componentDidMount. Le composant est simplement monté une fois, ce qui signifie que le premier modèle est celui qui reste sur la page et que les liens suivants modifient les accessoires mais laissent la page inchangée.

La définition du modèle dans l'état du composant dans componentDidMount et dans componentWillReceiveProps (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é.

2
Paul Whipp

Ce sujet est un peu vieux et résolu, mais je voudrais vous suggérer une solution simple, claire et meilleure. Cela fonctionne si vous utilisez un serveur Web.

Chaque serveur Web peut rediriger l'utilisateur vers une page d'erreur en 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'application Java), la solution pourrait être la suivante:

web.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>

Exemple:

  • GET http://example.com/about
  • Le serveur Web renvoie http 404 car cette page n'existe pas côté serveur
  • la configuration de la page d'erreur indique au serveur que la page index.jsp est renvoyée à l'utilisateur
  • alors JS fera le reste du travail du côté du client car l’url du côté client est toujours http://example.com/about .

C'est ça, plus besoin de magie :)

2
zappee

Pendant que j'utilise .Net Core MVC, quelque chose comme cela m'a aidé:

    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");
        }
   }

Fondamentalement du côté MVC, tous les itinéraires non correspondants tomberont dans Home/Index comme spécifié dans startup.cs. Dans Index, il est possible d’obtenir l’URL de la demande initiale et de la transmettre à tout moment.

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" });
        });
1
Elnoor

Au cas où quelqu'un chercherait ici 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 le côté client et le côté serveur . Dans votre modèle de lame, incluez le fichier js fourni, assurez-vous d'utiliser URL facade comme ceci

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

Dans vos itinéraires, assurez-vous d'ajouter ceci au noeud final principal où se trouve le modèle de lame. Par exemple,

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

Ce qui précède est le paramètre principal du modèle de lame. Ajoutez maintenant un itinéraire optionnel aussi,

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

Le problème qui se pose est que le modèle de lame est d'abord chargé, puis le routeur de réaction. Ainsi, lorsque vous chargez '/setting-alerts', il charge le code HTML et le code js. Mais lorsque vous chargez '/setting-alerts/about', il se charge d’abord du côté serveur. Du côté du serveur, il n'y a rien à cet emplacement, il retourne non trouvé. Lorsque vous avez ce routeur facultatif, il charge la même page et le routeur de réaction est également chargé, puis le chargeur de réaction détermine le composant à afficher . J'espère que cela vous aidera.

1
Koushik Das

Si vous utilisez Express ou un autre framework dans le backend, vous pouvez ajouter la configuration similaire à celle décrite ci-dessous et extraire le chemin public de Webpack dans la configuration. Cela devrait fonctionner même lors du rechargement si vous utilisez BrowserRouter

` expressApp.get('/*', (request, response) => {
    response.sendFile(path.join(__dirname, '../public/index.html'));
  });`
1
user2849063

Ajouter plus d'informations à La réponse de Joshua Dyck .

Si vous utilisez Firebase et souhaitez utiliser à la fois la route racine et une route de sous-répertoire, vous devez ajouter le code suivant dans votre firebase.json:

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

Exemple:

Vous construisez un site Web pour un client. Vous souhaitez que le propriétaire du site Web ajoute des informations dans https://votre.domaine.com/management pendant que les utilisateurs du site Web accèdent à https://votre.domaine.com .

Dans ce cas, votre fichier firebase.json ressemblera à ceci:

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

J'ai découvert une solution de contournement frontale qui ne nécessite aucune modification du serveur.

Supposons que votre site est mysite.com et que vous avez un React Route vers mysite.com/about. Dans index.js, où vous montez votre composant de niveau supérieur, vous pouvez placer un autre routeur tel que:

ReactDOM.render(
<Router>
    <div>
        <Route exact path="/" component={Home} />
        <Route exact path="/about"
            render={(props) => <Home {...props} refreshRout={"/about"}/>}
        />
    </div>
</Router>,

Je suppose que le routeur d'origine est situé quelque part en dessous du composant de niveau supérieur du DOM virtuel. Si vous utilisez Django comme _:

urlpatterns = [
       path('about/', views.index),
]

Cela dépendra du backend que vous utilisez, cependant. Demander mysite/about vous mènera à index.js (où vous montez le composant de niveau supérieur) où vous pouvez utiliser l'accessoire de rendu de Route, plutôt que l'accessoire de composant, et passer '/ about' comme accessoire à, dans cet exemple, le composant Accueil.

Dans Home, dans ComponentDidMount () ou le hook useEffect (), faites:

useEffect() {   
   //check that this.props.refreshRoute actually exists before executing the 
   //following line    
   this.props.history.replace(this.props.refreshRoute);
}

J'ai supposé que votre composant Home rendait quelque chose comme:

<Router>
   <Route exact path="/" component={SomeComponent} />
   <Route path="/about" component={AboutComponent} />
</Router>

Crédit à ( Passer les accessoires à un composant rendu par React Router ) pour savoir comment passer des accessoires aux composants dans Routes.

0
Stevie

Routeur complet avec exemple (React Router v4):

Exemple de travail Exemple Consultez le projet ci-dessous.

https://github.com/eh3rrera/react-router-4-example

Après le téléchargement 
1.) "Npm install" dans cmd pour installer le projet 
2.) "Npm start" pour démarrer votre application de réaction

Remarque: vous avez besoin du logiciel Node js pour fonctionner dans vos fenêtres. Mac OS ont noeud par défaut. 

À votre santé

0
Muthu Kumar

Pour ceux qui utilisent IIS 10, voici ce que vous devez faire pour remédier à cela. Assurez-vous que vous utilisez browserHistory avec cela. En ce qui concerne la référence, je donnerai le code pour l’acheminement, mais ce n’est pas ce qui compte, c’est l’étape suivante après le code du composant ci-dessous:

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"));

Étant donné que le problème est que IIS reçoit une demande des navigateurs clients, l'URL sera interprété comme s'il demandait une page, puis renvoyait une page 404 puisqu'il n'y avait pas de page disponible. Faites ce qui suit:

  1. Ouvrez IIS
  2. Développez Serveur puis ouvrez le dossier Sites.
  3. Cliquez sur le site/l'application
  4. Aller aux pages d'erreur
  5. Ouvrez l'élément d'état d'erreur 404 dans la liste
  6. Au lieu de l'option "Insérer le contenu du fichier statique dans la réponse d'erreur", remplacez-la par "Exécuter une URL sur ce site" et ajoutez "/" une valeur de barre oblique à l'URL.

Et cela va maintenant fonctionner correctement.

 enter image description here  enter image description here

J'espère que ça aide. :-)

0

J'utilise WebPack, j'ai eu le même problème Solution => Dans votre fichier server.js

const express = require('express');
const app = express();

app.use(express.static(path.resolve(__dirname, '../dist')));
  app.get('*', function (req, res) {
    res.sendFile(path.resolve(__dirname, '../dist/index.html'));
    // res.end();
  });

https://github.com/ReactTraining/react-router/blob/master/FAQ.md#why-doesnt-my-application-render-after-refreshing

0
Vishal Singh

Si vous hébergez dans IIS; Ajouter ceci à ma webconfig a résolu mon problème

    <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>

Vous pouvez effectuer une configuration similaire pour n’importe quel autre serveur.

0
Barny

Supposons que vous ayez la définition de route de départ suivante

<Route exact path="/" render={routeProps => (
   <Home routeProps={routeProps}/>
)}/>

{/*optional catch-all router */}
<Route render={routeProps => (
       <div><h4>404 not found</h4></div>
)}/>

Sur votre composant Home, vous pouvez intercepter la demande lors d’un événement ComponentWillMount,

const searchPath = this.props.routeProps.location.search;

if (searchPath){
    this.props.routeProps.history.Push("/" + searchPath.replace("?",""));
}
else{
    /*.... originally Home event */
}

Maintenant, au lieu d'appeler/joblist à l'url, vous pouvez demander /? Joblist, et le composant redirigera automatiquement la demande vers/joblist (notez le point d'interrogation supplémentaire dans le chemin).

0
user2674595

Si vous venez ici et que vous utilisez Apache et que vous n’avez pas de fichier .htaccess, c’est un fichier de configuration qui a fonctionné pour moi:

sites-enabled/somedomain.com.conf

<VirtualHost *:80>
    ServerName somedomain.com
    ServerAlias *.somedomain.com
    DocumentRoot /www/somedomain.com/build

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /www/somedomain.com/build/index.html [L,NC,QSA]

</VirtualHost>
0
DevB2F

J'ai eu ce même problème et ceci solution a fonctionné pour nous ..

Contexte:

Nous hébergeons plusieurs applications sur le même serveur. Lorsque nous actualiserions, le serveur ne comprendrait pas où chercher notre index dans le dossier dist de cette application particulière. Le lien ci-dessus vous amène à ce qui a fonctionné pour nous ... J'espère que cela vous aidera, car nous avons passé de nombreuses heures à trouver une solution à nos besoins. 

Nous utilisons:

package.json

"dependencies": {
"babel-polyfill": "^6.23.0",
"ejs": "^2.5.6",
"express": "^4.15.2",
"prop-types": "^15.5.6",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-redux": "^5.0.4",
"react-router": "^3.0.2",
"react-router-redux": "^4.0.8",
"redux": "^3.6.0",
"redux-persist": "^4.6.0",
"redux-thunk": "^2.2.0",
"webpack": "^2.4.1"
}

mon webpack.config.js

webpack.config.js

/* eslint-disable */
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const babelPolyfill = require('babel-polyfill');
const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
  template: __dirname + '/app/views/index.html',
  filename: 'index.html',
  inject: 'body'
});

module.exports = {
  entry: [
    'babel-polyfill', './app/index.js'
  ],
  output: {
    path: __dirname + '/dist/your_app_name_here',
    filename: 'index_bundle.js'
  },
  module: {
    rules: [{
      test: /\.js$/,
      loader: 'babel-loader',
      query : {
          presets : ["env", "react", "stage-1"]
      },
      exclude: /node_modules/
    }]
  },
  plugins: [HTMLWebpackPluginConfig]
}

mon index.js

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import Routes from './Routes'
import { Provider } from 'react-redux'
import { createHistory } from 'history'
import { useRouterHistory } from 'react-router'
import configureStore from './store/configureStore'
import { syncHistoryWithStore } from 'react-router-redux'
import { persistStore } from 'redux-persist'

const store = configureStore();

const browserHistory = useRouterHistory(createHistory) ({
  basename: '/your_app_name_here'
})
const history = syncHistoryWithStore(browserHistory, store)

persistStore(store, {blacklist: ['routing']}, () => {
  console.log('rehydration complete')
})
// persistStore(store).purge()


ReactDOM.render(
    <Provider store={store}>
      <div>
        <Routes history={history} />
      </div>
    </Provider>,
  document.getElementById('mount')
)

mon app.js

var express = require('express');
var app = express();

app.use(express.static(__dirname + '/dist'));
// app.use(express.static(__dirname + '/app/assets'));
app.set('views', __dirname + '/dist/your_app_name_here');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

app.get('/*', function (req, res) {
    res.render('index');
});

app.listen(8081, function () {
  console.log('MD listening on port 8081!');
});
0
J. Parrish

Correction de l'erreur "ne peut pas obtenir d'URL" lors de l'actualisation ou lors de l'appel direct de l'URL.

Configurez votrewebpack.config.jspour qu’il attende le lien donné les itinéraires comme ceci.

module.exports = {
  entry: './app/index.js',
  output: {
       path: path.join(__dirname, '/bundle'),
       filename: 'index_bundle.js',
       publicPath: '/'
    },
0
Lalit Tyagi

J'aime cette façon de le gérer. Essayez d’ajouter: yourSPAPageRoute/* côté serveur pour résoudre ce problème. 

Je suis allé avec cette approche parce que même l'API d'histoire HTML5 native ne prend pas en charge la redirection correcte sur l'actualisation de la page (autant que je sache).

Remarque: La réponse sélectionnée a déjà répondu à cette question, mais j'essaie d'être plus spécifique.

Express Route

 Test - History API Testé et je voulais juste partager ceci.

J'espère que ça aide.

0
Rehan

Solution pour pré-agir avec pré-routeur

Fonctionne avec rafraîchissement et accès direct

Pour ceux qui découvrent cela via Google, voici une démonstration de l'historique de preact-router + hash:

const { h, Component, render } = preact; /** @jsx h */
const { Router } = preactRouter;
const { createHashHistory } = History;
const App = () => (
    <div>
        <AddressBar />

        <Router history={createHashHistory()}>
            <div path="/">
                <p>
                    all paths in preact-router are still /normal/urls.
                    using hash history rewrites them to /#/hash/urls
                </p>
                Example: <a href="/page2">page 2</a>
            </div>
            <div path="/page2">
                <p>Page Two</p>
                <a href="/">back to home</a><br/>
            </div>
        </Router>
    </div>
);

https://jsfiddle.net/developit/gLyL6rbn/

0
keemor

J'ai trouvé la solution pour mon SPA avec le routeur de réaction (Apache). Ajoutez juste .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>

source: https://Gist.github.com/alexsasharegan/173878f9d67055bfef63449fa7136042

0
Sasha Ignashevich

Si vous utilisez firebase, il vous suffit de vous assurer que vous avez une propriété rewrites dans votre fichier firebase.json à la racine de votre application (dans la section hébergement). 

Par exemple:

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

J'espère que cela épargnera à quelqu'un un trésor de frustration et de perte de temps.

Bon codage ...

En savoir plus sur le sujet:

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

CLI Firebase: "Configurer comme une application à une seule page (réécrire toutes les URL dans /index.html)"

0
Joshua Dyck

C'est assez simple quand vous obtenez ne peut pas obtenir d'erreur 403 après l'actualisation du composant dom. ajoutez simplement cette ligne dans la configuration de votre pack Web, "historyApiFallback: true". ça vous fait toute ma journée.

0
praveenkumar s