浏览器跨域失败排障
区分实际请求、预检和凭据,检查响应来源策略与浏览器错误,不以 curl 成功替代浏览器验证。
适用范围与前提
浏览器 Fetch/XHR 的跨源请求;CORS 不是认证机制,也不控制服务器间请求。
- 替换示例 API 和 Origin 为已授权目标及真实页面来源(协议、主机、端口),不填写路径或多个来源。
- 先从浏览器 Network 留存失败阶段;请求会产生访问日志与可能的应用副作用,示例 GET 只能用于确认无写入的路径,OPTIONS 也需获授权。
- 不将真实 Cookie/Token 粘贴到公开报告或终端示例,不关闭浏览器安全、证书验证或访问控制。
命令仅供手动复制到获授权的环境执行。站点不会连接服务器;涉及网络的诊断可能产生请求或登录审计记录。
1. 先确定浏览器阻止请求的阶段
# 查看开发者工具 Network/Console:记录页面 Origin、方法、请求头名称、credentials 模式、OPTIONS 与实际请求状态。预期现象:简单请求通常无预检,但实际响应仍需 CORS 授权;非简单方法/请求头可能先发 OPTIONS。DNS、TLS、混合内容、CSP 或扩展阻断不等于 CORS 配置错误。
- OPTIONS 失败或实际请求未发出 → 仅模拟预检响应,不发送业务 POST
- 实际请求已返回但脚本不能读取 → 对照实际响应和凭据条件
- DNS、TLS、混合内容或其他限制 → 升级求助前收集
2. 仅模拟预检响应,不发送业务 POST
curl --max-time 5 -i -X OPTIONS 'https://api.example.com/health' -H 'Origin: https://app.example.com' -H 'Access-Control-Request-Method: POST' -H 'Access-Control-Request-Headers: content-type'预期现象:替换为浏览器实际的方法和请求头名称。检查状态、ACAO、允许方法/请求头,预检不应被登录重定向或因缺少 Cookie 拒绝;此命令仅发 OPTIONS,curl 自身不校验 CORS。
- 预检状态或允许方法/头不匹配 → 修复建议(需人工确认)
- 预检允许,继续检查实际响应 → 对照实际响应和凭据条件
- 上游、代理或身份系统责任不明 → 升级求助前收集
3. 对照实际响应和凭据条件
curl --max-time 5 -i 'https://api.example.com/health' -H 'Origin: https://app.example.com'预期现象:只对批准的只读 GET 路径执行;示例不会复用浏览器凭据,因此不与认证请求完全等价。ACAO 应为单个匹配来源;带凭据时不能是 *,还需 ACAC: true。错误响应同样需要恰当的 CORS 头。
- 缺头、重复来源、来源不匹配或通配来源与凭据冲突 → 修复建议(需人工确认)
- 动态来源或不同请求得到不同策略 → 核对动态来源和预检缓存
- 头符合预期但仍失败 → 检查浏览器凭据与可读响应头
4. 核对动态来源和预检缓存
# 对照已批准的不同 Origin 请求结果,检查 Vary: Origin、CDN 缓存键及 Access-Control-Max-Age;仅向响应头分析器粘贴头部,不粘贴正文。预期现象:动态回显允许来源时应按来源区分缓存,不能无条件反射任意 Origin。预检缓存与普通 HTTP 缓存不同,策略更新后旧授权可能暂存。
- 缓存键或来源白名单不正确 → 修复建议(需人工确认)
- 缓存策略正确 → 检查浏览器凭据与可读响应头
5. 检查浏览器凭据与可读响应头
# 人工检查 Fetch credentials、Cookie SameSite/Secure、第三方 Cookie 限制,以及脚本读取的响应头是否需要 Access-Control-Expose-Headers。预期现象:未发送 Cookie、401 或业务拒绝不应只靠放宽 CORS 解决;Expose-Headers 控制脚本能读取的非安全列表响应头,不替代 ACAO,也不能暴露 Set-Cookie。
- 客户端凭据或可读头配置明确不符需求 → 修复建议(需人工确认)
- 配置符合预期且真实浏览器恢复 → 验证恢复
- 无法定位浏览器策略或认证问题 → 升级求助前收集
修复建议(需人工确认)
- 按最小来源白名单统一代理/应用 CORS 责任,人工确认后修改并保留回退;不重复添加 ACAO 或无条件反射任意来源。
- 为批准的预检返回合适的方法/请求头策略,核对实际成功与错误响应;凭据模式使用明确来源,不配置通配来源授权凭据。
- 动态来源按需设置 Vary 与 CDN 缓存键,评估预检缓存时效;Cookie/认证变更需应用负责人确认,不使用 no-cors 或禁用浏览器安全绕过。
验证恢复
- 在原浏览器、原 Origin、实际方法/头和凭据模式下验证 OPTIONS 与实际请求,以及脚本能读取的内容。
- 对允许与不允许的来源分别验证预期策略;curl 成功只证明收到了 HTTP 响应,不证明浏览器 CORS 通过。
升级求助前收集
- 提供浏览器版本、脱敏 Origin、方法/头名称、凭据模式、OPTIONS/实际状态和 CORS 头;移除 Cookie、Token、正文及用户数据。