rmdir.cn
← 排障手册

浏览器跨域失败排障

区分实际请求、预检和凭据,检查响应来源策略与浏览器错误,不以 curl 成功替代浏览器验证。

适用范围与前提

浏览器 Fetch/XHR 的跨源请求;CORS 不是认证机制,也不控制服务器间请求。

  • 替换示例 API 和 Origin 为已授权目标及真实页面来源(协议、主机、端口),不填写路径或多个来源。
  • 先从浏览器 Network 留存失败阶段;请求会产生访问日志与可能的应用副作用,示例 GET 只能用于确认无写入的路径,OPTIONS 也需获授权。
  • 不将真实 Cookie/Token 粘贴到公开报告或终端示例,不关闭浏览器安全、证书验证或访问控制。

命令仅供手动复制到获授权的环境执行。站点不会连接服务器;涉及网络的诊断可能产生请求或登录审计记录。

1. 先确定浏览器阻止请求的阶段

# 查看开发者工具 Network/Console:记录页面 Origin、方法、请求头名称、credentials 模式、OPTIONS 与实际请求状态。

预期现象:简单请求通常无预检,但实际响应仍需 CORS 授权;非简单方法/请求头可能先发 OPTIONS。DNS、TLS、混合内容、CSP 或扩展阻断不等于 CORS 配置错误。

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、正文及用户数据。