QA 环境中 React 应用程序的 Nginx 和 Express Server 的 CORS 问题

问题描述 投票:0回答:1

我在 QA 环境设置中遇到持续存在的 CORS 问题。我的配置包括以下组件:

  1. 前端: React 应用程序托管在 EC2 实例上,通过 Nginx 提供服务。
  2. 后端:在同一 EC2 实例上运行的 Node.js Express API,由 Nginx 代理。
  3. CORS 配置:在 Express 服务器内处理,但从 localhost:3000 调用 API 进行本地开发时,我在 OPTIONS 请求期间收到 CORS 错误。

在浏览器控制台中看到的错误是:

Request URL: https://qa.example.com/auth/login
Request Method: OPTIONS
Status Code: 405 Not Allowed

Nginx 配置

worker_processes auto;
events { worker_connections 1024; }

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;

    sendfile on;
    tcp_nopush on;
    keepalive_timeout 65;
    types_hash_max_size 4096;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    # HTTP to HTTPS redirection
    server {
        listen 80;
        server_name qa.example.com;
        return 301 https://$host$request_uri;
    }

    # HTTPS server block
    server {
        listen 443 ssl;
        server_name qa.example.com;

        ssl_certificate /etc/letsencrypt/live/qa.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/qa.example.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        # Serve React frontend
        root /home/ec2-user/build;
        index index.html;

        location / {
            try_files $uri /index.html;
        }

        # Proxy requests to backend API
        location /api/ {
            proxy_pass http://localhost:5000/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

Express 服务器(server.js)

import express from 'express';
import dotenv from 'dotenv';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import http from 'http';
import { WebSocketServer } from 'ws';
import connectDB from './config/db.js';
import authMiddleware from './middlewares/authMiddleware.js';
import authRoutes from './routes/authRoutes.js';
// Other imports omitted for brevity

dotenv.config();

const app = express();
app.use(cookieParser());

// Allowed origins for CORS
const allowedOrigins = [
  'http://localhost:3000',  // Local development
  'https://qa.example.com', // QA environment
  'https://example.com',    // Production environment
];

// CORS options
const corsOptions = {
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
};

// Apply CORS
app.use(cors(corsOptions));

// Preflight handling for OPTIONS requests
app.options('*', cors(corsOptions));

// Middleware to parse JSON
app.use(express.json());

// MongoDB connection
connectDB();

// Define routes
app.use('/auth', authRoutes);
// Other routes omitted for brevity

// Create HTTP server
const server = http.createServer(app);

// WebSocket server initialization
const wss = new WebSocketServer({ server });
wss.on('connection', (ws) => {
  console.log('WebSocket connected');
});

// Start server
const PORT = process.env.PORT || 5000;
server.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

我尝试过的事情:

  1. Node.js 中的 CORS 处理:允许的来源包括用于本地开发的 localhost:3000、用于 QA 的 qa.example.com 以及用于生产的 example.com。
  2. 预检处理:Express 服务器配置为处理 OPTIONS 请求。
  3. Nginx 代理配置:我已经设置 Nginx 来代理请求 后端 API (/api)。
  4. Nginx Headers:在 Nginx 的 API 级别添加了必要的 CORS 标头。

问题: 尽管在 Express 服务器中正确配置了 CORS 并将 Nginx 设置为反向代理,我仍然收到 OPTIONS 请求的 405 状态代码。有什么我可能遗漏的东西或者解决这个问题的更好方法吗?

node.js nginx cors
1个回答
0
投票

您面临的 CORS 问题似乎源于与 Express 应用程序和 Nginx 设置中处理预检请求(选项)相关的潜在配置问题。但这只是根据我自己的经验做出的有根据的猜测

查看浏览器缓存:有时浏览器会缓存 CORS 预检结果。为了确保您使用新的标头进行测试,请清除浏览器缓存或在私人/隐身窗口中尝试请求。

仔细检查您在 CORS 配置中允许的标头:Express CORS 选项中的

allowedHeaders
包括“内容类型”和“授权”。如果您的前端发送任何其他标头,您需要将它们添加到允许列表中。例如,如果您要发送 X-Requested-With 标头,也请包含该标头。

验证 Express 服务器正在侦听 OPTIONS:如果您已经使用

app.options('*', cors(corsOptions));
设置 Express 服务器来处理 OPTIONS 请求,请确保您正在测试的端点 (
/auth/login
) 也包含在您的 CORS 配置中。

使用CURL测试CORS:您可以直接使用curl测试您的API端点:

curl -X OPTIONS https://qa.example.com/auth/page -H "Origin: http://localhost:3000" -i

此命令将显示服务器针对 OPTIONS 请求返回的响应标头。

问题解决了吗?

© www.soinside.com 2019 - 2024. All rights reserved.