如果用户更改浏览器,为什么我的react应用程序会显示“无法获取/ route”?

时间:2019-12-06 16:14:12

标签: node.js reactjs express npm react-router

我有一个使用React-Router和Express的React应用程序。我添加了一条新路由,该路由接受加密的私钥,并允许用户通过指向其电子邮件收件箱的链接自动登录。

这是路线:

<PublicRoute path="/loader/:user_key" component={Loader} />

{Loader}是一个具有componentWillMount()函数的React组件,该函数解析URL,获取“ user_key”,对用户进行身份验证,创建cookie并将其重定向到私有“ /”。家”路线。

链接非常有效-只要用户先前已经从相同浏览器登录到应用程序即可。但是,如果用户在一个浏览器(例如笔记本电脑)上创建了自己的帐户,并从其他浏览器(例如手机)打开了电子邮件链接,则浏览器将返回

  

“无法获取/ loader /...”

您有什么建议吗?我在做什么错了?

编辑

这是server.js文件(包含密钥表达逻辑)

const bodyParser = require("body-parser");
const expressValidator = require("express-validator");
const session = require("express-session");
const MongoStore = require("connect-mongodb-session")(session);
const mongoose = require("mongoose");
const passport = require("./config/passport/index.js");
const routes = require("./routes/index.js");
const express = require("express");
const app = express();
const http = require("http");
const path = require("path");
const PORT = process.env.PORT || 3001;
const MONGODB_URI =
  process.env.MONGODB_URI || "mongodb://localhost:27017/sonar";
mongoose.Promise = Promise;

//Parse application /x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

//Server instance
const server = http.createServer(app);

//Cronjobs
const cronjob = require("./cronjob.js");

// -------------------------- Sessions -----------------------------

//Initiate sessions
app.use(
  session({
    secret: "Secret",
    store: new MongoStore({ uri: MONGODB_URI, collection: "sessions" }),
    resave: true,
    saveUninitialized: true,
    cookie: {
      maxAge: 3*60*60*1000 // In milliseconds
    }
  })
);

//Initialize passport
app.use(passport.initialize());
app.use(passport.session()); // will call the deserializeUser

// --------------------- Backend Validation---------------------------

//This validates and sanitizes strings
app.use(
  expressValidator({
    errorFormatter: (param, msg, value) => {
      const namespace = param.split("."),
        root = namespace.shift(),
        formParam = root;

      while (namespace.length) {
        formParam += "[" + namespace.shift() + "]";
      }
      return {
        param: formParam,
        msg: msg,
        value: value
      };
    }
  })
);

// -------------------------- Routes -----------------------------

//Sets static assets path
app.use(express.static(path.join(__dirname, "/build")));

//Sets route to index
app.get("/", (req, res) => {
  // console.log("Is this firing? '/' ")
  res.sendFile(__dirname, "/index.html");
});

//Setting up routes in app
app.use(routes);

// -------------------------- MongoDB -----------------------------

// Connect to the Mongo DB
mongoose.connect(MONGODB_URI, { useNewUrlParser: true }, (err, db) => {
  if (err) {
    console.log("Unable to connect to the mongoDB server. Error:", err);
  } else {
    console.log("Connection established to", MONGODB_URI);
  }
});

const db = mongoose.connection;

// Show any mongoose errors
db.on("error", error => {
  console.log("Mongoose Error: ", error);
});

// Once logged in to the db through mongoose, log a success message
db.once("open", () => {
  console.log("Mongoose connection successful.");
});

// -------------------------- Listen -----------------------------

// Start the API server
app.listen(PORT, () => {
  console.log("App listening on PORT " + PORT);
});

编辑#2

一旦server.js返回index.html文件,问题似乎就在于加载React-Router。添加index.html文件以供参考:

 <!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-132577862-1"></script>

    <!-- Google Analytics -->
    <script>
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());

        gtag('config', 'UA-132577862-1');
    </script>

    <!-- This deactivates browser navigation button: "Back" -->
    <script type="text/javascript" >
       function preventBack(){window.history.forward();}
        setTimeout("preventBack()", 0);
        window.onunload=function(){null};
    </script>

    <!-- Stripe checkout -->
    <!-- <script src="https://checkout.stripe.com/checkout.js"></script> -->

    <!-- React Script -->
    <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

    <!-- <meta name="theme-color" content="#000000"> -->
    <link rel="manifest" href="manifest.json">

    <link rel="shortcut icon" href="profilePicture/infinity_preloader.gif">

    <!-- Bootstrap CDN -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" id="bootstrap-css">

    <!-- jquery -->
    <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>

    <!-- Moment.js (I don't think this is necessary - can delete?) -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script> -->

    <!-- This is the IE ES6 script work around -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.includes"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.5/bluebird.min.js"></script>


    <!-- iPhone PWA icon -->
    <link rel="apple-touch-icon" sizes="180x180" href="profilePicture/dummy_profile_Pic2.png"> 

    <!-- iPhone splash screens -->
    <link rel="apple-touch-startup-image" href="profilePicture/dummy_profile_Pic2.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" />

    <link rel="apple-touch-startup-image" href="profilePicture/dummy_profile_Pic2.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" />

    <link rel="apple-touch-startup-image" href="profilePicture/dummy_profile_Pic2.png" media="(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)" />

    <link rel="apple-touch-startup-image" href="profilePicture/dummy_profile_Pic2.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" />

    <link rel="apple-touch-startup-image" href="profilePicture/dummy_profile_Pic2.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)" />

    <link rel="apple-touch-startup-image" href="profilePicture/dummy_profile_Pic2.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)" />

    <link rel="apple-touch-startup-image" href="profilePicture/dummy_profile_Pic2.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)" />

    <!-- Fonts -->
    <!-- <link href="https://fonts.googleapis.com/css?family=Nunito+Sans" rel="stylesheet"> -->
    <link href="https://fonts.googleapis.com/css?family=Inconsolata|Lato|Nunito|Montserrat" rel="stylesheet">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

    <title>Cratic | The Culture Builder</title>
  </head>
  <body>
    <div id="root" ></div>
  </body>
</html>

1 个答案:

答案 0 :(得分:0)

在您的 server.js 快递文件中添加通配符路由,以捕获可能不匹配的所有路由并返回index.html文件,这允许react-router接管并在前端路由:

...

// -------------------------- Routes -----------------------------

//Sets static assets path
app.use(express.static(path.join(__dirname, "/build")));

//Sets route to index
app.get("/", (req, res) => {
  // console.log("Is this firing? '/' ")
  res.sendFile(__dirname, "/index.html");
});

//Setting up routes in app
app.use(routes);

// WILDCARD ROUTE HANDLER
app.get("*", (req, res) => {
  res.sendFile(__dirname, "/index.html");
};

...


这是完整的 server.js 文件:

const bodyParser = require("body-parser");
const expressValidator = require("express-validator");
const session = require("express-session");
const MongoStore = require("connect-mongodb-session")(session);
const mongoose = require("mongoose");
const passport = require("./config/passport/index.js");
const routes = require("./routes/index.js");
const express = require("express");
const app = express();
const http = require("http");
const path = require("path");
const PORT = process.env.PORT || 3001;
const MONGODB_URI =
  process.env.MONGODB_URI || "mongodb://localhost:27017/sonar";
mongoose.Promise = Promise;

//Parse application /x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

//Server instance
const server = http.createServer(app);

//Cronjobs
const cronjob = require("./cronjob.js");

// -------------------------- Sessions -----------------------------

//Initiate sessions
app.use(
  session({
    secret: "Secret",
    store: new MongoStore({ uri: MONGODB_URI, collection: "sessions" }),
    resave: true,
    saveUninitialized: true,
    cookie: {
      maxAge: 3*60*60*1000 // In milliseconds
    }
  })
);

//Initialize passport
app.use(passport.initialize());
app.use(passport.session()); // will call the deserializeUser

// --------------------- Backend Validation---------------------------

//This validates and sanitizes strings
app.use(
  expressValidator({
    errorFormatter: (param, msg, value) => {
      const namespace = param.split("."),
        root = namespace.shift(),
        formParam = root;

      while (namespace.length) {
        formParam += "[" + namespace.shift() + "]";
      }
      return {
        param: formParam,
        msg: msg,
        value: value
      };
    }
  })
);

// -------------------------- Routes -----------------------------

//Sets static assets path
app.use(express.static(path.join(__dirname, "/build")));

//Sets route to index
app.get("/", (req, res) => {
  // console.log("Is this firing? '/' ")
  res.sendFile(__dirname, "/index.html");
});

//Setting up routes in app
app.use(routes);

// WILDCARD ROUTE HANDLER
app.get("*", (req, res) => {
  res.sendFile(__dirname, "index.html");
}

// -------------------------- MongoDB -----------------------------

// Connect to the Mongo DB
mongoose.connect(MONGODB_URI, { useNewUrlParser: true }, (err, db) => {
  if (err) {
    console.log("Unable to connect to the mongoDB server. Error:", err);
  } else {
    console.log("Connection established to", MONGODB_URI);
  }
});

const db = mongoose.connection;

// Show any mongoose errors
db.on("error", error => {
  console.log("Mongoose Error: ", error);
});

// Once logged in to the db through mongoose, log a success message
db.once("open", () => {
  console.log("Mongoose connection successful.");
});

// -------------------------- Listen -----------------------------

// Start the API server
app.listen(PORT, () => {
  console.log("App listening on PORT " + PORT);
});

让我知道您是否有错误或者这不能解决问题!