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

Apache2 Proxy跨子域请求时Cookie请求头丢失问题排查

跨子域请求代理后Cookie丢失解决方案

问题复现场景

  • api.example.com 虚拟主机配置/internal路径反向代理到本地8760端口的Node.js服务,代理配置如下:
ProxyRequests on
ProxyPreserveHost on
ProxyPass /internal http://localhost:8760
ProxyPassReverse /internal http://localhost:8760
  • 同源(源为api.example.com)发起如下AJAX请求时,Node.js后端可正常读取Cookie头:
$.ajax({
    type: "GET",
    url: "https://api.example.com/internal/ajax",
    dataType: "json",
    cache: false
});
  • 仅修改请求发起源为同根域下的sample.example.com,其余请求参数不变时,跨域请求到达后端后仅Cookie头缺失,其余请求头正常。

核心原因

跨源请求默认会被浏览器剥离Cookie、Authorization等敏感身份凭证头,这是浏览器内置的安全限制,必须同时满足三个条件才会在跨域请求中携带Cookie:

  • 前端请求显式开启携带凭证配置
  • 服务端返回的跨域响应头明确允许凭证传输,且不能用通配符*设置允许源
  • 目标Cookie的作用域配置允许跨子域访问

分步修复方案

1. 前端请求开启跨域凭证配置

修改AJAX请求参数,添加跨域携带凭证的开关:

$.ajax({
    type: "GET",
    url: "https://api.example.com/internal/ajax",
    dataType: "json",
    cache: false,
    // 新增以下两行配置
    xhrFields: {
        withCredentials: true
    },
    crossDomain: true
});

其他请求客户端对应配置:原生fetch设置credentials: 'include';axios设置withCredentials: true。

2. Apache补充跨域响应头配置

在api.example.com的虚拟主机配置中,为/internal路径添加跨域头:
注意:禁止将Access-Control-Allow-Origin设置为通配符*,否则跨域凭证配置不生效,必须明确声明允许的源

<Location /internal>
    # 单允许源直接写死即可,多子域场景可通过mod_rewrite校验请求Origin是否属于*.example.com后动态赋值
    Header set Access-Control-Allow-Origin "https://sample.example.com"
    # 显式允许跨域携带凭证
    Header set Access-Control-Allow-Credentials "true"
    # 声明允许的请求头
    Header set Access-Control-Allow-Headers "Content-Type,Cookie,Authorization"
    # 声明允许的请求方法
    Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS"

    # 直接响应OPTIONS预检请求,无需转发到后端Node服务
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} OPTIONS
    RewriteRule ^(.*)$ $1 [R=204,L]
</Location>

# 原有代理配置保留不变
ProxyRequests on
ProxyPreserveHost on
ProxyPass /internal http://localhost:8760
ProxyPassReverse /internal http://localhost:8760

配置完成后执行apachectl configtest校验配置无错,重启Apache服务生效。

3. 校验Cookie作用域配置

确保api.example.com下写入的Cookie满足跨子域访问要求:

  • Cookie的Domain属性设置为.example.com(前缀带点,覆盖所有example.com下的子域),如果Domain默认设置为api.example.com,跨子域请求无权携带该Cookie
  • HTTPS环境下Cookie需要开启Secure属性,同时将SameSite属性设置为None,否则跨域场景下浏览器会拦截Cookie
    Node.js(Express框架)写Cookie参考配置:
res.cookie('user_token', 'xxxx', {
    domain: '.example.com',
    httpOnly: true,
    secure: true,
    sameSite: 'None',
    maxAge: 7 * 24 * 3600 * 1000
});

所有配置修改完成后,清空浏览器站点缓存、旧Cookie后重新测试即可正常读取到跨域请求携带的Cookie头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:21:18