为啥 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 应用程序上运行?的主要内容,如果未能解决你的问题,请参考以下文章