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

纯HTML页面script标签中fetch请求本地接口失败原因咨询

问题根因

这个报错和框架无关,核心是浏览器同源策略触发的CORS(跨域资源共享)拦截:

  • 浏览器默认禁止脚本向和当前页面不同源(协议、域名、端口三者任意一个不一致)的接口发起请求,防止恶意站点窃取数据,拦截发生在浏览器侧,请求要么根本没发出去,要么响应被浏览器拦截,前端就会拿到TypeError: Failed to fetch的通用错误。
  • 你之前React项目请求正常,是因为React本地开发服务(通常跑在3000端口)配置了代理规则:/api开头的请求会被开发服务自动转发到后端端口,浏览器视角下请求始终发往当前页面所在的3000端口,属于同源请求,自然不会被拦截。如果去掉代理直接跨端口请求后端,React项目一样会报相同错误。
  • 你直接双击打开本地HTML文件时,页面的源是file://协议,和后端接口的http://localhost:5000源完全不匹配,直接触发跨域拦截。
  • 当你通过Express的5000端口返回HTML页面时,页面访问地址是http://localhost:5000,和接口地址http://localhost:5000/api/*完全同源,没有跨域限制,所以请求能正常工作。

另外你的现有后端代码还存在一个隐藏bug:没有配置JSON请求体解析中间件,就算跨域问题解决,POST接口里的req.body会是undefined,拿不到前端传的参数。

修复方案

根据你的开发场景选对应方案即可:

方案1:前后端同源部署(你当前已经在用的方式)

把前端静态文件都交给Express服务托管,所有页面和接口都走同一个5000端口,天然不存在跨域问题,适合小型项目部署。注意要补上缺失的中间件配置,在所有路由注册前加两行代码:

// 解析JSON格式请求体
app.use(express.json());
// 如果你有静态资源(css、js、图片等),加这行托管public文件夹
app.use(express.static(path.join(__dirname, "public")));

方案2:前后端分离部署/本地单独打开HTML调试

给Express配置CORS中间件,允许指定源的跨域请求:

  1. 安装cors依赖:
    npm install cors
    
  2. 在Express入口文件中,所有路由注册前添加配置:
    const cors = require("cors");
    const app = express();
    
    // 开发环境可直接放开所有跨域请求
    app.use(cors());
    // 生产环境建议只配置允许的前端源,比如:
    // app.use(cors({ origin: "http://你的前端页面地址" }))
    
    // 别忘了加JSON解析中间件
    app.use(express.json());
    
    // 后面再写app.use("/api", testRoute)这类路由注册逻辑
    

注意:部分浏览器会直接拦截file://协议源的跨域请求,即使配了CORS也无法正常请求,本地调试建议用静态文件服务(比如VSCode的Live Server插件)打开HTML,再把Live Server的地址加入CORS允许列表即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:06:29