type
status
date
slug
summary
tags
category
icon
password
📌 理解 CORS:Preflight、响应控制与 no-cors
模式
跨域资源共享(CORS, Cross-Origin Resource Sharing)是浏览器的安全机制,限制 Web 应用从不同源请求数据。开发者需要正确理解 预检请求(Preflight)、响应控制(Response Control) 和
no-cors
测试模式,以确保 API 能够安全、正确地跨域访问。1️⃣ Preflight(预检请求):前端如何触发?
当前端的
fetch
请求不符合 简单请求 规则(比如 POST
+ Content-Type: application/json
),浏览器会先发送一个 OPTIONS
预检请求,询问服务器是否允许这个跨域请求。🔹 前端请求
🔹 浏览器会先自动发送
2️⃣ 后端如何处理 Preflight?
后端必须正确响应
OPTIONS
预检请求,否则浏览器不会继续发送 POST
。🔹 后端
OPTIONS
响应如果
OPTIONS
失败(返回 403
、404
或 500
),浏览器不会继续发送 POST
,API 不会执行。✅ Node.js 处理
OPTIONS
✅ Cloudflare Workers 处理
OPTIONS
3️⃣ Preflight 成功后,后端执行 API 逻辑
如果
OPTIONS
响应正确,浏览器才会继续发送 POST
,后端代码才会执行。🔹 前端
POST
请求🔹 后端 API 响应
✅ 正确设置
Access-Control-Allow-Origin
,前端可以读取 API 响应。4️⃣ Preflight
通过但 Access-Control-Allow-Origin
不正确
如果
OPTIONS
成功,但后端 POST
响应中的 Access-Control-Allow-Origin
不匹配前端的 Origin
,浏览器会拦截响应,前端无法获取数据。🔹 错误示例
❌ 即使
POST
请求执行了,前端仍然会报 CORS 错误,拿不到数据。✅ 解决方案
- 确保
OPTIONS
和POST
的Access-Control-Allow-Origin
一致:
- 如果 API 允许多个来源,动态检查
Origin
:
5️⃣ mode: "no-cors"
绕过 Preflight
如果前端使用
mode: "no-cors"
,浏览器不会发送 OPTIONS
预检请求,而是直接发 POST
,但前端无法访问 API 响应(opaque response)。🔹 前端代码
🔹 后端仍然会执行 API 逻辑,但浏览器不会检查
Access-Control-Allow-Origin
,前端拿不到任何响应内容。✅ 什么时候用
no-cors
?- 测试后端 API 是否执行,无视 CORS 规则。
- 但无法读取响应数据,不适合获取 API 结果。
6️⃣ no-cors
+ credentials: "include"
的安全风险
如果 API 允许
SameSite=None; Secure
的 Cookie,且前端使用 mode: "no-cors" + credentials: "include"
,可能导致 CSRF 攻击。🔹 恶意网站可以执行
❌ 攻击者无法读取 API 响应,但可以在受害者的会话里执行敏感操作,比如修改密码。
✅ 如何防止 CSRF?
- 避免
SameSite=None
,优先SameSite=Lax
。
- 后端检查
Origin
,拒绝跨站请求:
- 使用 CSRF Token,确保请求来自受信任的前端。
🎯 结论
OPTIONS
预检失败,POST
请求不会发送,后端 API 不会执行。
OPTIONS
通过但Access-Control-Allow-Origin
不匹配,API 执行但前端拿不到数据。
mode: "no-cors"
绕过OPTIONS
,API 仍然执行,但前端无法读取响应。
no-cors + credentials: "include"
可能导致 CSRF,必须使用Origin
检查或 CSRF Token 保护。
掌握这些知识,就能正确处理 CORS,同时保证 API 安全性!🚀