You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同域下React+Node文件下载时出现CORS错误求助

React下载文件触发CORS错误问题

问题描述

后端服务器域名是https://example.com:3000,React应用由Apache托管在https://example.com,其他API接口都能正常响应,但从服务器下载文件时出现CORS错误,具体错误提示:

Access to fetch at 'https://example.com:3000/uploads/private-79-38/1676275634939-chats.pdf' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

相关代码

React前端代码

<Link to="#" className="text-decoration-none">
  <button
    className="dropdown-item "
    type="button"
    onClick={() => {
      console.log("called");
      let headers = new Headers();
      headers.append("Content-Type", "application/json");
      headers.append("Accept", "application/json");

      fetch(file.file_path, {
        headers: headers,
      })
        .then((res) => {
          console.log(res);
          return res.blob();
        })
        .then((blob) => {
          console.log(blob);
          const href = window.URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.download = file.file_real_name;
          a.href = href;
          a.click();
          a.href = "";
        });
    }}
  >
    Download
  </button>
</Link>;

Node.js后端代码

app.use(cors());

错误截图

CORS错误截图

解决方法

1. 确保静态文件请求经过CORS中间件

你的cors()中间件可能只处理了API路由,而uploads目录下的静态文件直接由静态文件服务处理,没经过CORS配置。调整后端代码顺序,先挂载CORS再配置静态文件:

const express = require('express');
const cors = require('cors');
const app = express();

// 先加载CORS中间件,让所有请求都经过它
app.use(cors());
// 再配置静态文件服务,确保uploads下的文件请求也带上CORS头
app.use('/uploads', express.static('uploads'));

2. 移除不必要的请求头

你在fetch里设置的Content-Type: application/json和Accept: application/json不适合下载PDF文件,会触发浏览器的预检OPTIONS请求,而静态文件服务可能没处理这类请求。简化fetch代码:

<Link to="#" className="text-decoration-none">
  <button
    className="dropdown-item "
    type="button"
    onClick={() => {
      fetch(file.file_path)
        .then((res) => res.blob())
        .then((blob) => {
          const href = window.URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.download = file.file_real_name;
          a.href = href;
          a.click();
          // 释放URL对象资源,避免内存泄漏
          window.URL.revokeObjectURL(href);
        });
    }}
  >
    Download
  </button>
</Link>;

3. 明确指定允许的跨域来源

开发环境用http://localhost:3000,生产环境用https://example.com,可以针对性配置CORS:

// 开发环境允许localhost,生产环境允许example.com
const allowedOrigins = ['http://localhost:3000', 'https://example.com'];
app.use(cors({
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  }
}));

4. 用反向代理彻底规避跨域

如果后端和前端同域名,可以在Apache配置反向代理,把https://example.com/uploads的请求转发到https://example.com:3000/uploads,这样前端直接请求同域名路径,彻底解决CORS问题。示例Apache配置:

ProxyPass /uploads https://example.com:3000/uploads
ProxyPassReverse /uploads https://example.com:3000/uploads

内容的提问来源于stack exchange,提问作者pankaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:01:12