繁体   English   中英

手动刷新或写入时,React 路由器 URL 不起作用。 并获取 html 数据而不是 JSON 数据

[英]React router URL don't work when refreshing or writing manually. and getting html data instead of JSON data

我正在使用 React-router 的 MERN 网站上工作,当我单击链接按钮时它工作正常,但是当我刷新我的网页时,它没有加载我想要的内容。 手动刷新或写入时,React 路由器 URL 不起作用。 所以我看到了很多解决这个问题的方法。 我使用了一种解决方案,即捕获 server.js 中的每个 get 请求并发送 index.html 文件。

if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "client", "build")));

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

 }

这个过程完美地解决了反应路由器的问题,但在客户端,我通过发送 Axios get 请求来获取一些数据。

useEffect(() => {
          
        axios
            .get("/posts")
            .then((result) => {
                console.log(result.data);
      //result.data contains index.html file instead of json data
                
            })
            .catch((error) => {
                console.log(error);
            });
    }, []);

该 get 请求的响应应该具有 get JSON 数据,但它获得了 index.html 文件。 我知道它会获取那个 index.html 文件,因为我在捕获 server.js 中的所有请求时发送了 index.html 文件。

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

但是如果我删除那行代码,那么在手动刷新或编写 URL 时,我会遇到 React 路由器 URL 不起作用的错误。 我想要的是解决反应路由器问题,并从该请求中获取 JSON 数据并使用该数据来映射这些数据。 这是我的 server.js、App.js 和 Posts.js 代码

服务器.js

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
require("dotenv").config();
const path = require("path");

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));

// parse application/json
app.use(bodyParser.json());

if (process.env.NODE_ENV === "production") {
    app.use(express.static(path.join(__dirname, "client", "build")));

    app.get("/*", function (req, res) {
        res.sendFile(path.join(__dirname, "client", "build", "index.html"));
    });
}
mongoose
    .connect(process.env.MONGODB_URI, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true,
        useFindAndModify: false,
    })
    .then(() => {
        console.log("Database connected");
    })
    .catch((err) => {
        console.log(`Database error ${err.message}`);
    });

const postsSchema = new mongoose.Schema({
    title: {
        type: String,
    },
    description: {
        type: String,
    },
});

const Posts = new mongoose.model("Posts", postsSchema);

app.get("/posts", (req, res) => {
    Posts.find({}, (error, post) => {
        if (error) {
            res.json(error.message);
        } else {
            res.json(post);
        }
    });
});


    
app.listen(process.env.PORT || 5000, () => {
    console.log("App started in port 5000");
});

应用程序.js

import "./App.css";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Posts from "./Posts";
import Header from "./Header";

function App() {
    return (
        <div className="App">
            <Router>
                <Header />
                <Switch>
                    
                    <Route exact path="/posts" component={Posts} />
                    
                </Switch>
            </Router>
        </div>
    );
}

export default App;

Posts.js

import React, { useState, useEffect } from "react";
import axios from "axios";
import { Link } from "react-router-dom";

function Posts() {
    const [posts, setPosts] = useState([]);

    useEffect(() => {
        axios
            .get("/posts")
            .then((result) => {
                setPosts(result.data);
                console.log(result.data);
               //result.data contains index.html file instead of JSON data
            })
            .catch((error) => {
                console.log(error);
            });
    }, []);

    return (
        <div className="container mt-5">
            <div className="row">
                {posts.map((post) => {
                    return (
                        <div className="col-sm-3" key={post._id}>
                            <h6>{post.title}</h6>
                            <p>{post.description}</p>

                            <Link className="nav-link active" to={`/post/${post._id}`}>
                                Read More
                            </Link>
                        </div>
                    );
                })}
            </div>
        </div>
    );
}

export default Posts;

如果您知道我的代码有什么问题,请帮助我。 以及如何获取 JSON 数据而不是 index.html 文件

const express = require("express");
//const bodyParser = require("body-parser"); not necessary
const mongoose = require("mongoose");
require("dotenv").config();
const path = require("path");

const app = express();

//app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.urlencoded({ extended: false }));
//app.use(bodyParser.json());
app.use(express.json());

/*if (process.env.NODE_ENV === "production") {
    app.use(express.static(path.join(__dirname, "client", "build")));

    app.get("/*", function (req, res) {
        res.sendFile(path.join(__dirname, "client", "build", "index.html"));
    });
}*/
mongoose
    .connect(process.env.MONGODB_URI, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true,
        useFindAndModify: false,
    })
    .then(() => {
        console.log("Database connected");
    })
    .catch((err) => {
        console.log(`Database error ${err.message}`);
    });

const postsSchema = new mongoose.Schema({
    title: {
        type: String,
    },
    description: {
        type: String,
    },
});

const Posts = new mongoose.model("Posts", postsSchema);

// Static Files Folder
app.use(express.static(path.join(__dirname,"client","bluild")))

// Routes
app.use("/posts", (req, res)=>{
    Posts.find({}, (error, post) => {
        if (error) {
            res.json(error.message);
        } else {
            res.json(post);
        }
    });
})
app.use("/*", (req, res)=>{res.sendFile(path.join(__dirname,"public/index.html"))}) /*always at the end*/

app.listen(process.env.PORT || 5000, () => {
    console.log("App started in port 5000");
});

那应该有效,现在我想给你一些提示。

  • 最新版本中的 Express 包括 body-parser 如果您打算使用 1 个处理客户端 + 服务器端的服务器(我的意思是不使用 create-react-app 并创建其他服务器来发出请求):
  • 拳头,您必须清除静态文件夹,您将在其中放置用 react 制作的包(在您的情况下,我认为它是 index.js)。
  • 没有必要为不存在的路由重新发送包,您可以向客户端发送一个 json (res.json({Status: 'NotFound'})) 并且您必须在那里显示用户该页面不存在(使用反应,创建一个组件 NotFound 并确保它是路由中的最后一个路由)或只发送 res.status(401)。 但是,如果您使用下一点,这不是必需的。
  • 在 react-router 中,你应该使用“HashRouter as Router”而不是“BrowserRouter as Router”,解释起来有点困难,你可以找到它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM