web-dev-qa-db-fra.com

React Router BrowserRouter conduit à l'erreur "404 Not Found - nginx" lors de l'accès direct à la sous-page sans passer par un clic sur la page d'accueil

J'utilise React Router pour le routage d'un site Web de plusieurs pages. Lorsque j'essaie d'accéder directement à une sous-page https://test0809.herokuapp.com/signin vous obtiendrez une erreur "404 Not Found -nginx" (pour pouvoir voir ce problème, vous devrez peut-être accéder à ce lien en mode navigation privée afin qu'il n'y ait pas de cache). Tous les liens fonctionnent correctement si vous allez à partir de la page d'accueil : test0809.herokuapp.com/. J'utilisais BrowserRouter et j'ai pu éliminer l'erreur "404 non trouvé" en changeant BrowserRouter en HashRouter, ce qui donne à toutes mes URL un signe "#". Outre tous les problèmes liés à la présence d'un "#" dans vos URL, le plus gros problème est que j'ai besoin d'implémenter LinkedIn Auth dans mon site Web, et LinkedIn OAuth 2.0 ne permet pas de rediriger les URL vers contient #. LinedIn OAuth 2.

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import LinkedIn from 'react-linkedin-login'
const Home = () => <div><h2>Home</h2></div>
const About = () => <div><h2>About</h2></div>
class Signin extends Component {
  callbackLinkedIn = code => {
    console.log(1, code)
  }
  render() {
      return (
          <div>
              <h2>Signin</h2>
              <LinkedIn
                  clientId="clientID"
                  callback={this.callbackLinkedIn}
              >
          </div>
      )
  }
}
const BasicExample = () =>
  <Router>
    <div>
      <ul>
         <li>
           <Link to="/">Home</Link>
         </li>
         <li>
           <Link to="/about">About</Link>
         </li>
         <li>
           <Link to="/signin">Signin</Link>
         </li>
      </ul>
  <hr />

      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/signin" component={Signin} />
    </div>
  </Router>
export default BasicExample

Des suggestions sur les solutions de contournement?

Contexte: J'ai commencé le projet avec create-react-app. Dépôt GitHub: /debelopumento/test0809

14
Di Ye

solution en deux étapes (l'étape 1 est mentionnée dans React-Router README https://github.com/mars/create-react-app-buildpack#routing-clean-urls ):

Étape 1, ajoutez un fichier static.json à la racine:

{
 "root": "build/",
 "clean_urls": false,
 "routes": {
   "/**": "index.html"
 }
}

Étape 2, ajoutez ce buildpack Heroku: https://github.com/heroku/heroku-buildpack-static.git

0
Di Ye

Le problème est que nginx ne sait pas quoi faire avec /signin. Vous devez modifier votre configuration nginx (généralement dans /etc/nginx/conf.d/) pour servir votre index.html quel que soit l'itinéraire. Voici un exemple de configuration nginx qui pourrait vous aider:

server {
  listen 80 default_server;
  server_name /var/www/example.com;

  root /var/www/example.com;
  index index.html index.htm;      

  location ~* \.(?:manifest|appcache|html?|xml|json)$ {
    expires -1;
    # access_log logs/static.log; # I don't usually include a static log
  }

  location ~* \.(?:css|js)$ {
    try_files $uri =404;
    expires 1y;
    access_log off;
    add_header Cache-Control "public";
  }

  # Any route containing a file extension (e.g. /devicesfile.js)
  location ~ ^.+\..+$ {
    try_files $uri =404;
  }

  # Any route that doesn't have a file extension (e.g. /devices)
  location / {
    try_files $uri $uri/ /index.html;
  }
}
32
Mark Rabey

Ajoutez simplement try_files $uri $uri/ /index.html; à location / bloc dans le fichier de configuration NGINX comme ceci:

server {
   listen       80;
   server_name  localhost;

   location / {
       root   /build;
       index  index.html;
       try_files $uri $uri/ /index.html;
   }
}
1
Chhaileng