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

React+Node.js项目HTTPS域名下非GET请求跨域缺失Allow Origin头报错求助

问题说明

我使用React.js开发前端应用,对接Node.js后端服务。用服务器IP地址在前端调用API时一切正常,切换为域名HTTPS访问后,仅GET请求可正常执行,POST、DELETE、PUT等所有其他请求均无法正常工作。

  • Axios执行API请求返回报错栈:
Error: Network Error
    at n.exports (createError.js:16)
    at XMLHttpRequest.g.onerror (xhr.js:84)
  • 使用fetch发起请求返回报错:

TypeError: Failed to fetch

我已经尝试过两类CORS配置方案,均无效果:

  1. 手动设置CORS响应头
app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', '*')
    res.setHeader('Access-Control-Allow-Methods','OPTIONS, GET, POST, PUT, PATCH, DELETE')
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
    next()
})
  1. 使用cors中间件
const cors = require('cors');
app.use(cors())

前端请求示例代码:

await axios.put(`${baseUrl}/users/updateProfil/${id}`, data, {
          headers: {
            'Content-Type': 'application/json' ,
            'Authorization': `Bearer ${JSON.parse(token)}`
          }
        })
        .then(res => res.data).catch((e)=>{
          alert(e);
            console.log(e)
        });

后端用户资料更新接口实现代码:

router.put('/updateProfil/:id', async (req, res) => {
  var userId = req.params.id;
  var first_name = req.body.first_name;
  var last_name = req.body.last_name;
  var email = req.body.email;
  var country = req.body.country;
  var city = req.body.city;
  var phone = req.body.phone;
  var sender_sms_name = req.body.sender_sms_name;
  if (
    email &&
    phone &&
    city &&
    country &&  
    first_name &&
    last_name && 
    sender_sms_name
  )  {
    var user = await User.findOne({
      $or: [{ phone: phone }, { email: email }],
    }).select('-password').catch((error) => {
      res.status(404).json({
        success: false,
        val: 0,
        data: "error",
        message: "Something went wrong.",
      });
    }); 
    if (user != null) {
       await User.findByIdAndUpdate(userId, {
        first_name: first_name,
        email: email,
        last_name: last_name,
        phone: phone,
        city: city,
        country: country,
        sender_sms_name: sender_sms_name}, {new: true})
      .then( async(user) => {
        user= await User.populate(user, {path: 'sub_account'})
        return res.status(200).json({
          success: true,
          val: 1,
          data: user,
          message: "update done ",
        });
      });
    }else{
      return res.status(404).json({
        success: true,
        val: 1,
        data: "error while updating",
        message: "update success ! ",
      });
    }
   
  }else {
    return res.status(404).json({
      success: false,
      val: 0,
      data: "impossible to update!",
      message: "verify fields please.",
    });
  }
});
解决方案

请按以下优先级逐一排查:

  1. 检查反向代理/CDN配置
    这是90%以上HTTPS域名切换后非GET请求失败的原因:IP访问时是直接请求Node.js服务,切换域名后大概率走了Nginx、Apache等反向代理或者云CDN,这类服务默认会拦截PUT、DELETE等非通用HTTP方法。

    • 如果你使用Nginx反向代理,需要在站点配置的location块中添加允许对应方法的配置,同时直接处理OPTIONS预检请求,无需转发到Node服务:
    location / {
        proxy_pass http://你的Node服务内网地址:端口;
        proxy_method GET;
        proxy_method POST;
        proxy_method PUT;
        proxy_method DELETE;
        proxy_method OPTIONS;
        
        if ($request_method = OPTIONS ) {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods "OPTIONS, GET, POST, PUT, DELETE, PATCH";
            add_header Access-Control-Allow-Headers "Content-Type, Authorization";
            return 204;
        }
    }
    
    • 如果你使用了云服务商的CDN、WAF服务,需要到对应控制台配置允许PUT、DELETE等请求方法,部分服务商默认只放行GET、HEAD、POST三种方法。
  2. 检查baseUrl协议配置
    确认前端配置的baseUrl是https://开头,不要残留http://,HTTPS站点发起HTTP请求会被浏览器的混合内容策略直接拦截,也会返回网络错误。

  3. 修复后端预检请求处理逻辑
    你当前的手动CORS配置没有单独处理OPTIONS预检请求,非简单请求(带自定义头的PUT、POST等)浏览器会先发送OPTIONS预检请求,你的代码直接把OPTIONS请求转发给了路由,而路由没有对应OPTIONS的处理逻辑,会返回404导致请求失败。可以在手动CORS配置里增加预检请求判断:

app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', '*')
    res.setHeader('Access-Control-Allow-Methods','OPTIONS, GET, POST, PUT, PATCH, DELETE')
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
    // 预检请求直接返回204
    if(req.method === 'OPTIONS') {
        return res.sendStatus(204)
    }
    next()
})

注意手动CORS配置和cors中间件不要同时使用,避免配置冲突,二选一即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:48:04