原来只知道有CORS是因为浏览器同源策略引起的,所以如果前端调用后端Restful API的时候浏览器会报跨域的问题;
看完CSRF相关的内容,跨站点请求伪造,即便有同源策略,浏览器会拦截响应,但是该执行的API还是已经执行过了。
CORS 是浏览器为了解决跨域请求的问题而设计的一种机制,后端通过设置 HTTP 响应头(如 Access-Control-Allow-Origin
)告诉浏览器:我允许这个域的请求访问我的资源。
“简单请求”:
符合以下条件的请求,浏览器直接发起请求,不会预检:
- 方法是 GET、POST 或 HEAD;
- Content-Type 限于:
application/x-www-form-urlencoded
,multipart/form-data
,text/plain
; - 无自定义请求头;
这些请求如果不被 CORS 允许,浏览器会拦截响应(但请求已经发送了) 。
🔍 示例:简单请求跨域时依旧执行 API
const formData = new URLSearchParams();
formData.append('email', email);
formData.append('name', name);
formData.append('password', password);
fetch(`${API_URL}/auth/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded', // ✔️ 属于简单请求
},
body: formData,
});
✅ 上面的请求是跨域的,而且会有跨域问题,但是仍旧会创建一个新的用户,用户会被保存到数据库; 这是一个典型的“简单请求”,即使跨域时 CORS 没设置允许,浏览器也会把请求发送出去!只是响应内容会被拦截,JavaScript 拿不到响应数据。
⚠️ “非简单请求”:
如使用 PUT、DELETE 方法或带自定义请求头的 POST 请求,会先发送一个预检请求(OPTIONS) ,询问服务器是否允许,再决定是否发送真正的请求。
🔥 和 CORS 的关系?
- CSRF 攻击通常是“同源策略绕不过”的,因为攻击的页面和目标 API 是跨域的。
- 但是跨域的 POST 请求(简单请求)是会直接发出的,哪怕响应被浏览器拦截,后端逻辑已经执行了。
🔐 安全建议
same site cookie只允许顶级域名相同的情况下携带cookie,不适用于前后端分离且前后端域名不同的情况; 这时后端设置的sameSite是None;
//前端代码
fetch("https://api.backend.com/api/xxx", {
method: "POST",
credentials: "include", // 👈 关键点:允许浏览器带上 Cookie
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
//后端代码
res.cookie("backendToken", token, {
httpOnly: true,
secure: true, // 必须是 HTTPS 才能使用 SameSite=None
sameSite: "None", // 明确允许跨站携带 Cookie
});
由于你在跨站传递 Cookie,浏览器已不再默认信任行为,所以要注意:
- 使用
https://
,不要部署在 HTTP 上。 - 后端验证
Origin
或Referer
头,配合 CSRF Token 做双重验证(提高安全性)。 - 如果使用 JWT,尽量使用短有效期 + Refresh Token 机制。
🔐 前端安全防御方法汇总
1. 防止 XSS(跨站脚本攻击)
-
输入过滤 + 输出转义
- 所有用户输入进行严格校验(白名单优先)。
- 对动态插入 DOM 的内容使用转义(如
innerText
替代innerHTML
)。
-
使用安全框架
- React、Vue 默认对绑定内容进行转义。
-
Content Security Policy(CSP)
-
限制可执行的脚本来源,例如:
-
HTTP-ONLY cookie防止cookie泄漏
Content-Security-Policy: script-src 'self'
2. 防止 CSRF(跨站请求伪造)
-
使用 SameSite Cookie 策略
- 推荐设置:
Set-Cookie: token=xxx; SameSite=Strict; HttpOnly; Secure
-
Strict
: 拒绝第三方携带 Cookie,前后端不分离时使用。 -
Lax
: 支持 GET 导航请求,适合大多数表单场景。
-
配合 Token 校验
- 前端每次请求带上 CSRF Token,在服务端验证。
-
禁止第三方表单提交
- 使用
X-Requested-With: XMLHttpRequest
检测是否来自前端代码。
- 使用
-
正确使用DOM操作
- 使用
textContent
/innerText
,不要用innerHTML
插入不可信内容。
- 使用