首页 > 解决方案 > 在 Heroku 托管的我的 React 应用程序中,反应浏览器路由器可以成功引导确切的路由,但找不到动态路由

问题描述

在学习和部署 MERN 应用程序时,我能够在 heroku 上成功地托管我的 MERN 应用程序。

但是,当登录我的应用程序时,api/login 效果很好。但是,后续调用 api/getUserData 会抛出 404 错误。

非常感谢任何帮助......在此先感谢。

我的客户 Package.json

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:4080",
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "axios": "^0.19.2",
    "lodash": "^4.17.15",
    "pure-react-carousel": "^1.27.1",
    "query-string": "^6.12.1",
    "react": "^16.13.1",
    "react-datasheet": "^1.4.4",
    "react-dom": "^16.13.1",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.1",
    "react-select": "^3.1.0",
    "semantic-ui-react": "^0.88.2",
    "serve": "^11.3.2",
    "xlsx": "^0.16.1",
    "yarn": "^1.22.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

我的 Server.js 文件:

const express = require("express");
const mongoose = require("mongoose");
const http = require("http");
const passport = require("passport");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const env = require("dotenv");
const cors = require("cors");
// const socketIO = require("socket.io");

// const routes = require("./routes");
const app = express();
var PORT = process.env.PORT || 4080;
const server = http.createServer(app);

var db = require("./models");
// Connect to the Mongo DB
mongoose.connect(
  "mongodb://mydbNme:myPassword@ds119406.mlab.com:19406/heroku_4cz61gjp",
  {
    useUnifiedTopology: true,
    useNewUrlParser: true,
  }
);

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(cors({ origin: "http://localhost:3000", credentials: true }));

// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
  app.use(express.static("web/client/build"));
  const path = require("path");
  app.get("*", (req, res) => {
    res.sendFile(path.resolve(__dirname, "web/client/build", "index.html"));
  });
}

// We need to use sessions to keep track of our user's login status
require("./config/passport");
app.use(
  session({
    secret: "keyboard cat",
    resave: true,
    saveUninitialized: true,
    cookie: {
      maxAge: 24 * 60 * 60 * 1000,
    },
  })
);

app.use(passport.initialize());

app.use(passport.session());
require("./routes/apiRoutes.js")(app, db);

// Start the API server
server.listen(PORT, function () {
  console.log(`  ==> API Server now listening on PORT ${PORT}!`);
});

我的服务器 package.json:

 {
      "name": "appName",
      "version": "1.0.0",
      "description": "my description",
      "main": "web/server.js",
      "dependencies": {
        "bcrypt": "^4.0.1",
        "concurrently": "^5.2.0",
        "cookie-parser": "^1.4.5",
        "cors": "^2.8.5",
        "dotenv": "^8.2.0",
        "express": "^4.17.1",
        "express-session": "^1.17.1",
        "http": "^0.0.1-security",
        "mongodb": "^3.5.9",
        "mongoose": "^5.9.7",
        "passport": "^0.4.1",
        "passport-local": "^1.0.0",
        "path": "^0.12.7",
        "qrcode": "^1.4.4",
        "yarn": "^1.22.4"
      },
      "devDependencies": {},
      "scripts": {
        "start": "node web/server.js",
        "start:prod": "node web/server.js",
        "start:dev": "concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
        "server": "nodemon server.js",
        "client": "cd web/client && npm run start",
        "install": "cd web/client && npm install",
        "build": "cd web/client && npm run build",
        "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix web/client && npm run build --prefix web/client"
      },
      "repository": {
        "type": "git",
        "url": "git+https://github.com/github/github.git"
      },
      "engines": {
        "node": "12.x"
      },
      "author": "user1",
      "license": "ISC"
    }

我正在使用浏览器路由器的反应 app.js 文件。

import React from "react";
import "./App.css";
// import { Button } from 'semantic-ui-react';
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Login from "./pages/Login";
import SignUp from "./pages/SignUp";
import API from "./utils/API";
import Dashboard from "./pages/Dashboard";
import DisplayMenu from "./pages/DisplayMenu";
import Sample from "./pages/Sample";
import MenuDetails from "./pages/MenuDetails";
import Home from "./pages/Home";
import ANNavbar from "./components/ANNavbar";

class App extends React.Component {
  // this.getZipCode = this.getZipCode.bind(this)
  state = {
    isLoggedIn: false,
    isSticky: true,
    username: "",
    email: "",
    userId: "",

  };



  onuserLogin = (data) => {
    // this.setState({ isLoggedIn: data });
    this.setState({ isLoggedIn: data });

    API.getUserData()
      .then((res) => {
        console.log("Response from get user data ", res);
        this.setState({
          email: res.data.email,
          username: res.data.name,
          userId: res.data.id,
        });

        console.log(this.state);
      })
      .catch((err) => console.log(err));
  };

  onuserLogout = (data) => {
    this.setState({
      isLoggedIn: data,
      email: null,
      username: null,
      userId: null,
    });
  };

  render() {
    console.log("State of app js", this.state);
    const {
      isLoggedIn,
      username,
      userId,
      email,
      zipCode,
    } = this.state;
    return (
      <div id="page_body">
        <BrowserRouter>
          <ANNavbar />

          <Switch>
            <Route
              path="/login"
              render={() => (
                <Login
                  isAuthed={true}
                  onuserLogin={this.onuserLogin}
                />
              )}
            />
            <Route
              path="/signUp"
              render={() => <SignUp isLoggedIn={isLoggedIn} />}
              exact
            />
            <Route
              path="/dashboard"
              render={() => (
                <Dashboard
                  isLoggedIn={isLoggedIn}
                  username={username}
                  userId={userId}
                  email={email}
                />
              )}
              exact
            />
            <Route
              path="/displayItems/:userId"
              render={(props) => (
                <DisplayMenu
                  {...props}

                />
              )}
            />

              )}
            />
          </Switch>
        </BrowserRouter>
      </div>
    );
  }
}

export default App;

标签: reactjsexpressheroku

解决方案


我确实让它工作了。这是我所做的 对于动态端点,我添加了一条专门指向 index.html 的路由。我不确定这是否是最好的解决方案,但在找到更好的解决方案之前,我将使用它作为解决方法。

app.get("/displayItems/:param", function (req, res) {
    res.sendFile(path.join(__dirname, "../client/build", "index.html"));
  });

推荐阅读