Node.js配置cors后Axios请求仍报CORS跨域Network Error问题
Axios PUT请求触发CORS报错、无CORS响应头问题排查
问题现象
发起Axios PUT请求时触发跨域报错:
已在server.js中安装并引入cors模块,先后尝试配置{origin: "http://localhost:3000"}、空参数cors()两种模式均未生效,网络面板的响应信息中不存在任何CORS相关响应头:
关联代码
服务端入口 server.js
const express = require("express"); const mongoose = require("mongoose"); const apiRoutes = require('./routes/apiRoutes'); const path = require('path'); const cors = require("cors") require("dotenv").config(); const app = express(); const PORT = 3001; app.use(cors()); app.use(express.static(path.join(__dirname, 'images'))); app.use(express.urlencoded({ extended: false })); app.use(express.json()); app.use(apiRoutes); mongoose .connect(process.env.MONGO_URL) .then(res => console.log("The connection to the Database was carried out successfully.")) .catch(error => console.log(`The Error while connecting to the Database occured: ${error.message}`)) app.listen(PORT, 'localhost', error => console.log(error ? `The Error occured: ${error.message}.` : `The Listening Port is ${PORT}`) );
接口路由代码
router.put("/api/newAd/:creationDate", (req, res) => { console.log(req.body); // Ad.updateOne({ creationDate: req.body.creationDate }, { // textInfo: req.body // }) })
客户端请求代码
const saveAndPlace = () => { axios.put(`/api/newAd/${creationDate}`) .catch(err => console.log("error", err)) };
报错根因
- 核心问题是接口未返回任何响应:当前PUT路由的处理函数仅打印了请求体,既没有放开注释的数据库操作逻辑,也没有调用
res.send()/res.json()/res.end()等任何返回响应的方法,请求会被直接挂起直到超时。cors中间件的逻辑是在响应返回阶段注入CORS相关响应头,请求没有走到正常响应流程,自然不会携带CORS头。 - PUT请求属于CORS规范中的非简单请求,浏览器会先发送OPTIONS预检请求校验跨域权限,当前服务既没有正常响应业务请求,也没有匹配到OPTIONS请求的处理逻辑,预检请求直接失败,浏览器就会抛出跨域报错。
- 额外排查点:客户端请求用的是
/api开头的相对路径,如果前端开发服务(运行在3000端口)没有配置代理将/api请求转发到3001端口的Express服务,请求会直接打到前端服务自身,根本没有到达配置了cors的后端服务,也会出现同样的无CORS头、跨域报错现象。
修复方案
- 给所有路由处理函数补全响应逻辑,测试阶段哪怕不操作数据库也要返回明确响应,注意路径参数需要从
req.params获取,参考写法:
router.put("/api/newAd/:creationDate", (req, res) => { console.log(req.body); Ad.updateOne({ creationDate: req.params.creationDate }, { textInfo: req.body }).then(() => { res.json({ code: 200, msg: "更新成功" }) }).catch(err => { res.status(500).json({ code: 500, msg: err.message }) }) })
- 校验前端请求路径配置:如果没有配置前端开发服务代理,就给axios配置baseURL为
http://localhost:3001,确保请求能到达Express服务;如果用代理模式,确认代理配置中/api前缀的请求会转发到3001端口。 - 当前
cors中间件的注册位置在路由加载之前,顺序是正确的,接口正常返回响应后会自动携带CORS相关响应头,不需要额外调整配置。
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

