为啥 CORS 不能在我的 express/react 应用程序上运行?

Posted

技术标签:

【中文标题】为啥 CORS 不能在我的 express/react 应用程序上运行?【英文标题】:Why is CORS not working on my express/react app?为什么 CORS 不能在我的 express/react 应用程序上运行? 【发布时间】:2021-11-07 16:18:03 【问题描述】:

我将 npm cors 包与我的 react 应用程序和 express(OOP 方法)一起使用,但我仍然收到 CORS 错误:

从源“http://localhost:3000”访问“http://localhost:8000/api/auth/authenticate”的 XMLHttpRequest 已被 CORS 策略阻止:没有“访问控制允许源”请求的资源上存在标头。

我在后端设置了cors(),位于localhost:8000。我在前端使用 withCredentials: true 调用api,在localhost:3000

所以我不确定哪里出错了。

我的设置如下。谢谢,

后端 - express.middleware.ts

import cors from "cors";
import express from "express";

module.exports = (app: any) => 
  app.use(
    cors(
      origin: "http://localhost:3000",
      methods: ["POST", "PUT", "GET", "OPTIONS", "HEAD"],
      credentials: true,
    )
  );

  app.use(express.static("public"));
;

后端 - app.ts

import express from "express";
import dotenv from "dotenv";
import path from "path";

class App 
  private _app: express.Application;
  private readonly _port: number | string = process.env.PORT || 8000;

  constructor(controllers: any[]) 
    this._app = express();
    dotenv.config();

    this.initializeControllers(controllers);
    this.initializeMiddleWares();
  

  public start() 
    this._app.listen(this._port, () => 
      console.log(`App listening on the port $this._port`);
    );
  

  private initializeControllers(controllers: any[]) 
    controllers.forEach((controller) => 
      this._app.use("/api", controller.router);
    );
  

  public initializeMiddleWares() 
    require("./src/middleware/express.middleware")(this._app);
  


export default App;

后端 - server.ts

import App from "./app";
import AuthController from "./src/modules/auth/auth.controller";
import  AuthService  from "./src/modules/auth/auth.service";

const server = new App([new AuthController(new AuthService())]);

server.start();

前端 - useGet.ts(自定义挂钩调用 api)

import React from "react";
import  useHistory  from "react-router-dom";
import axios from "axios";
import  server_url  from "../constants";

const useGet = () => 
  const history = useHistory();
  const doGet = (path: string, cb?: Function) => 

    axios
      .get(`$server_url$path`,  withCredentials: true )
      .then((response) => 
        if (cb) 
          cb(response.data);
        
      )
      .catch((err) => 
        console.log(err);
      );
  ;

  return [doGet];
;

export default useGet;

【问题讨论】:

【参考方案1】:

在配置路由之前初始化中间件。

来自the docs:

如果当前中间件函数没有结束请求-响应循环,它必须调用next() 将控制权传递给下一个中间件函数。否则,请求将被挂起。

在您的情况下,控制器确实结束了请求-响应周期,因此中间件永远不会采取行动。

要修复它,请更改:

class App 
  // ...
  constructor(controllers: any[]) 
    // ...
    this.initializeControllers(controllers);
    this.initializeMiddleWares();
  

进入这个(注意行的顺序):

class App 
  // ...
  constructor(controllers: any[]) 
    // ...
    this.initializeMiddleWares();
    this.initializeControllers(controllers);
  

你应该很高兴。

【讨论】:

以上是关于为啥 CORS 不能在我的 express/react 应用程序上运行?的主要内容,如果未能解决你的问题,请参考以下文章

尝试从 localhost:8080 向 localhost:3000 发出 GET 请求,但出现 cors 错误,并且在我的 node.js 服务器上安装 cors 并不能修复它

为啥 Chrome 会取消 CORS OPTION 请求

为啥 CORS 错误“对预检请求的响应未通过访问控制检查”?

为啥 Laravel 中间件 CORS 不能与 Vue.js 一起使用

为啥我在 Spring Boot 中从服务器端配置并做出反应时出现 CORS 错误?

CORS服务器端与客户端?为啥一个工作,但另一个 - 不?