简单请求也要 Allow-Origin
GET、HEAD 或符合安全列名与 Content-Type 限制的 POST 可以跳过预检,但跨域响应仍要通过 Access-Control-Allow-Origin 检查。
开发 / FETCH & CORS
输入页面、接口和请求细节,先判断浏览器是否发送预检,再用服务端策略验证 Origin、凭据、方法与请求头能否真正通过。
REQUEST
OPTIONS /users HTTP/1.1 Origin: https://app.example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: authorization, content-type, x-request-id
SERVER POLICY
VERDICT
浏览器先验证 OPTIONS 响应;预检成功后才发送真实请求。
OUTPUT
Access-Control-Allow-Origin: https://app.example.com Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-Id Access-Control-Max-Age: 600 Access-Control-Expose-Headers: X-Request-Id
GET、HEAD 或符合安全列名与 Content-Type 限制的 POST 可以跳过预检,但跨域响应仍要通过 Access-Control-Allow-Origin 检查。
credentials: include 需要服务端返回明确 Origin 和 Access-Control-Allow-Credentials: true;`*` 不能作为带凭据响应的允许来源。
动态回显请求 Origin 时先在服务端做精确白名单匹配,并返回 Vary: Origin,避免 CDN 把一个来源的许可结果复用给其他来源。
预检与安全请求判断依据 WHATWG Fetch CORS protocol。 页面只模拟浏览器协议与响应头,不会向输入的接口发请求,也不会判断 Cookie 的 SameSite、第三方 Cookie、TLS、代理或应用认证是否正确。
RELATED TOOLS
USE & REVIEW
CORS 是浏览器 Fetch 的跨域读取协议,Postman、curl 和服务器到服务器请求通常不会执行同一套检查。因此接口能正常返回不等于网页可以读取。应在真实页面环境查看 Origin、OPTIONS 预检和最终响应头,而不是通过关闭浏览器安全设置掩盖服务端配置问题。
跨域请求只要方法不是 GET、HEAD、POST,或包含非 CORS 安全列名、application/json 等非安全 Content-Type,通常就会先预检。Authorization 也会触发预检。即使请求不预检,实际响应仍必须返回符合当前 Origin 的 Access-Control-Allow-Origin。
不能把多个 Origin 用逗号拼在一个 Header 中。固定单一来源时返回一个明确 Origin;允许多个来源时,服务端要读取请求 Origin,做严格白名单匹配,然后只回显这一项,并返回 Vary: Origin,防止缓存把一个来源的许可响应给另一个来源。
带 credentials 的跨域响应必须返回明确的 Access-Control-Allow-Origin,并提供 Access-Control-Allow-Credentials: true,不能使用 *。即使这两项正确,Cookie 还受 SameSite、Secure、Domain、第三方 Cookie 限制和浏览器隐私策略影响,CORS 通过不代表 Cookie 一定会发送。
不能把它当作访问控制。CORS 主要限制浏览器页面读取跨域响应,攻击者仍可使用服务器、脚本或自己的客户端直接请求接口。真正的保护依靠认证、授权、CSRF 防护、输入校验、速率限制与审计;允许 Origin 也不代表这个来源的所有用户都有权限。
预检与实际请求是两次独立响应。检查 OPTIONS 是否返回允许的方法和请求头,实际响应是否也有 Allow-Origin,错误状态与重定向是否经过了没有 CORS Header 的代理层,以及 CDN 是否缓存了其他 Origin 的结果。浏览器控制台提示只是入口,网络面板中的完整请求链更可靠。