【问题标题】:react app express server CORS request did not succeedreact app express server CORS请求没有成功
【发布时间】:2022-01-08 17:50:42
【问题描述】:

我正在尝试将我的前端连接到我的后端,并且我正在使用带有节点的快速服务器并做出反应。

这是我的前端获取请求:服务器在端口 5000 上运行

const response = await axios.post("http://localhost:5000/send-email", {
  to_email: data.data.email,
  url: data.data.url,
});

console.log(response);

结果如下:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/send-email. (Reason: CORS request did not succeed). Status code: (null).

我的后端有:

app.post("/send-email", async (req, res) => {
  try {
    const { to_email, url } = req.body;
    console.log(to_email, url);
    await sendMail()
      .then((result) => console.log("Email sent...", result))
      .catch((error) => console.log(error.message));

    res.send({ express: "YOUR EXPRESS BACKEND IS CONNECTED TO REACT" });
  } catch (error) {
    console.log(error);
    res.status(500).json({ message: error });
  }
});

我也在使用核心,还有类似的东西:

// app.use(function (req, res, next) {
//   // res.header("Access-Control-Allow-Origin", "*");
//   res.header("Access-Control-Allow-Origin", "http://localhost:3000");

//   res.header(
//     "Access-Control-Allow-Headers",
//     "Origin, X-Requested-With, Content-Type, Accept"
//   );
//   res.header("Access-Control-Allow-Methods", "POST, OPTIONS");
//   res.header("Access-Control-Allow-Credentials", true);

//   next();
// });

但我一直收到这个错误,我不知道如何摆脱它。我见过几个解决方案,它们要么是旧的,要么我尝试了其中一些,但它们根本不起作用。

【问题讨论】:

  • 为什么“类似这样”的代码都被注释掉了?
  • 好吧,既然那没有做任何事情,我只是将其注释掉,它根本没有帮助!
  • 你在你的服务器上使用了 cors 库吗? const cors = require('cors'); app.use(cors({ origin: '*', methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,COPY', preflightContinue: false, optionsSuccessStatus: 204, }) );
  • 是的,我喜欢这样: const cors = require("cors");和 app.use(cors());
  • 可以在axios.post的第三个参数中填充一个header。 axios.post(URL、数据、标题)

标签: node.js reactjs express cors


【解决方案1】:
  1. 使用 (npm install cors) 安装 cors。
  2. 在您的后端代码文件中,添加
    var cors = require('cors') <br />
    app.use(cors())
    

或者,按照https://www.npmjs.com/package/cors 提供的说明进行操作。

【讨论】:

  • 我已经有cors了,但还是会出现这种情况!
【解决方案2】:

我将其修复如下: 在我的前端,我有

const response = await axios.post("http://localhost:8000/signup", {
          newUserNameEmail,
          url,
        });

        console.log("response--> ", response.data);

在我的后端服务器中:

const PORT = 8000;
const express = require("express");
const cors = require("cors");
const nodemailer = require("nodemailer");
const { google } = require("googleapis");


const app = express();
app.use(cors());
app.use(express.json());

//sign up
app.post("/signup", async (req, res) => {
  try {
    const { newUserNameEmail, url } = req.body;

    console.log(newUserNameEmail, url);

    await sendMail(newUserNameEmail, url)
      .then((result) => console.log("Email sent...", result))
      .catch((error) => console.log(error.message));

    res.status(200).json({ newUserNameEmail, url });
  } catch (error) {
    console.log(error);
    res.status(500).json({ message: error });
  }
});

因此,出于某种原因,这可以正常工作并且不会产生我之前遇到的错误。我现在可以与前端和后端通信并发送数据和电子邮件。

但我不知道为什么这有效而另一个无效。我也没有改变我的 package.json

【讨论】:

    【解决方案3】:

    一种方法是在你的 React 应用程序中使用代理。

    您可以通过将此行添加到您的 package.json 文件中来实现此目的:"proxy": "http://localhost:8000" 这对于开发来说很好。 所以你的 package.json 看起来像 create-react-app:

    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
      // use correct port of your localhost API 
      // and pay attention that there is no slash behind the port
      // if you use slash in your app like this: /api
      "proxy": "http://localhost:8000", 
    

    在您的 react 应用程序中,您现在可以 POST 到您的端点 /send-mail。由于package.json 已更改,需要重新启动应用程序

    const response = await axios.post("/send-email", {
      to_email: data.data.email,
      url: data.data.url,
    });
    

    如果这不够灵活,也可以使用包http-proxy-middleware 手动添加代理。对于这个src/setupProxy.js 需要使用以下代码创建,另请参阅create-react-app 的文档here

    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    module.exports = function(app) {
      app.use(
        '/api',
        createProxyMiddleware({
          target: 'http://localhost:5000',
          changeOrigin: true,
        })
      );
    };
    

    package.json 中带有代理的完整示例

    前端反应

    在 http://localhost:3000 上运行

    将用于演示目的的硬编码数据发送到后端。 我的服务器在 8000 端口上运行,所以我在 package.json 中使用:“proxy”:“http://localhost:8000”:

    "scripts": {
      "start": "react-scripts start",
      "build": "react-scripts build",
      "test": "react-scripts test",
      "eject": "react-scripts eject"
    },
    "proxy": "http://localhost:8000",
    
    import axios from "axios";
    
    const App = () => {
      const postToBackend = async () => {
        const res = await axios.post("/send-mail", {
          to_email: "testmail@test.com",
          url: "test-uri",
        });
    
        console.log(res.data);
      };
    
      return <button onClick={() => postToBackend()}>send to backend</button>;
    };
    
    export default App;
    

    后端 Node.js

    在 http://localhost:8000 上运行

    从反应前端和控制台读取传入数据并记录数据。 我的文件夹结构:

    ├── app.js
    └── routes
        └── api
            └── test.js
    

    test.js 路由 该路由会解析请求体,打印出来,返回状态为 200。

    const express = require("express");
    const router = express.Router();
    
    router.post("/", async (req, res) => {
      const { to_email, url } = req.body;
    
      try {
        // this will print the test-email and test-uri hard coded in frontend
        console.log(to_email, url);
        // return values with status 200
        res
          .status(200)
          .json({ message: `Incoming data is ${to_email} and ${url}` });
      } catch (error) {
        res.status(400).json({ message: error.message });
      }
    });
    
    module.exports = router;
    
    

    app.js

    在 app.js 中只注册路由,在我的例子中,我是这样做的:

    const express = require("express");
    
    // express app
    const app = express();
    app.use(express.json());
    
    
    // tell express to use /send-mail as endpoint for 
    // above route (stored in folder routes/api/test.js
    app.use("/send-mail", require("./routes/api/test"));
    
    
    // run server
    const PORT = process.env.PORT || 8000;
    app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
    
    

    就是这样,您应该可以将数据从前端发送到后端。

    【讨论】:

    • 这重定向到 POST localhost:3000/send-email 这是不正确的!
    • 这就是代理正在做的事情——你基本上是在告诉你的 react 应用你的 API 在同一个域上——你从前端 POST 到 localhost:3000/send-mail 并且应该看到控制台localhost:8000 API 路由上的 .log() 输出(后端代码中的这一行:console.log(to_email, url);
    • 我收到此错误:POSThttp://localhost:3000/send-email 错误:请求失败,状态码为 404,但在网络选项卡下我可以看到我的请求正文
    • 您是否重新启动了应用程序,但仍然收到 404?
    • 是的,我重新启动了应用程序,但错误仍然存​​在
    【解决方案4】:

    在你的 package.json 文件中添加代理到你后端 api 的端口

    "proxy": "http://localhost:8000"
    

    然后将请求中的 url 更改为端口 3000 或前端所在的任何位置

    const response = await axios.post("http://localhost:3000/send-email", { 
      to_email: data.data.email,
      url: data.data.url,
    });
    
    console.log(response);
    

    代理只能在本地工作,但是您的应用和 api 通常共享相同的主域,因此此 cors 错误不会出现在生产中..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      • 2020-05-25
      • 2019-09-15
      相关资源
      最近更新 更多