🌍 CORS 测试
从选择的 Origin 发送 CORS 预检(OPTIONS)和实际请求,验证 Access-Control-Allow-Origin / Methods / Headers / Credentials / Max-Age。
完全免费
无需注册
服务器处理
无日志 / 数据库
限速
5 种语言
深色模式
📚 CORS 基础
• 浏览器会阻止对不同源的 fetch / XHR 请求。
• CORS 让服务器通过 Access-Control-Allow-Origin 声明"允许的源"。
• 预检请求是浏览器在实际请求之前发送的OPTIONS请求。当使用自定义标头或非简单方法 (PUT、DELETE 等) 时会发生。
• Access-Control-Allow-Credentials: true 不能与 Access-Control-Allow-Origin: * 组合 — 必须使用特定的 origin。
📖 本诊断能告诉你什么
本诊断会实际发送带 Origin 标头的请求以及预检 OPTIONS,并查看返回的 Access-Control-* 标头。需要牢记的前提是:只有浏览器会强制执行 CORS,curl 与服务器间通信完全不看它。因此 CORS 并非保护 API 的机制,而是防止恶意站点擅自使用用户浏览器中已保存的凭据的机制。
| 检查项 | 含义 | 未通过时的处理 |
|---|---|---|
| 罗列了多个来源 | Access-Control-Allow-Origin 中只能写一个来源或 *。用逗号罗列多个的写法在规范上无效,浏览器会整条拒绝。这是「明明配置了却仍报 CORS 错误」的极常见原因。 |
请在服务器端把请求的 Origin 与白名单比对,只原样返回匹配到的那一个。此时响应会随 Origin 变化,因此务必加上 Vary: Origin。若遗漏,CDN 会缓存第一次的响应,并把它发给其他来源。 |
| 每次请求都触发预检 | 发送 Content-Type: application/json、添加 Authorization 或自定义标头、使用 GET / POST / HEAD 之外的方法——只要其一,请求就不再是简单请求,正式请求之前会多出一次 OPTIONS 往返。每次调用 API 往返翻倍,在高延迟网络上体感明显。 |
请在 Access-Control-Allow-Headers 中完整列出实际会发送的标头(少写一个预检就会失败),并用 Access-Control-Max-Age 缓存预检结果。Chrome 的上限是 7200 秒,超过该值会被静默截断。 |
| 错误响应缺少 CORS 标头 | 许多框架在异常导致 500 时会绕过中间件,于是响应不带 Access-Control-Allow-Origin。浏览器因此不允许读取响应体,控制台里只显示「CORS 错误」。真正的原因——服务器端异常——被彻底掩盖。 |
请为异常处理器与 error_page 的响应加上相同的 CORS 标头。排查时应先在开发者工具的 Network 面板查看真实状态码。若是 500 或 404,则与 CORS 配置无关,应修复的是应用本身。 |
CORS 不是授权。无论是否设置 Access-Control-Allow-Origin: *,任何人依然可以用 curl 调用该 API。若有需要保护的数据,请实现令牌认证或会话校验。另一个常见误解是「配置了 CORS 就能防住 CSRF」,这并不成立,因为 <form> 提交与 <img> 加载本就不在 CORS 的管辖范围内。防 CSRF 需要另行使用 SameSite Cookie 与 CSRF 令牌。