文章目录
实习中遇到的 CORS 同源策略自己的理解分析:

跨域设置是在服务器端(后端)完成的,而不是在浏览器或前端代码里
简单回顾:
它的核心是同源策略 :浏览器只允许网页(源 A)请求来自同源(协议+域名+端口都相同)的资源(源 A)。如果网页(源 A)去请求不同源(源 B)的资源,浏览器就会发起一个"跨域"请求。
浏览器在发起跨域请求时,会附带一个 Origin 头,告诉服务器:"你好,我是从 https://your-frontend.com 来的。"
然后,服务器(后端)必须明确回应:"我允许 https://your-frontend.com 访问我。" 这个回应是通过 Access-Control-Allow-Origin 等响应头来完成的。
如果服务器没有返回这些允许访问的头,或者返回的 Origin 不匹配,浏览器就会拦截响应,前端代码就拿不到数据,并在控制台报 CORS 错误。
同源限制
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Allow-Credentials (允许携带的凭证)
前端的开发服务器需要配置的:
javascript
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
server: {
// 这就是"给前端页面加跨域请求的设置"
cors: true, // 或者进行更详细的配置
host: '0.0.0.0' // 允许局域网内其他设备访问 这个地方一般打开,也可以设置 CROS
}
})
前端(允许谁能拿到网页)和后端(允许从哪网页来的数据可以访问)都能配置,不过主要还是在后端配置滴~
前端开发服务器的代理:
javascript
// vite.config.js
export default defineConfig({
server: {
proxy: {
// 当前端代码请求 '/api' 开头的接口时
'/api': {
// 开发服务器会把这个请求转发到真正的后端服务器
target: 'https://api.company.com',
changeOrigin: true, // 修改请求头中的 Origin,让它看起来像是后端服务器自己的请求
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
用户请求: http://你的IP:8080/api/user (你的 IP:8080 可替换为我给的域名就好理解了)(基于自己本地的 localhost 根路径请求)
然后开发服务器进行改写然后发送给后端服务器
如果是同事访问同一局域网我的服务器:"你的 IP 就是对应启动了 vite 等代理服务器":
走的是这个流程:
同事的浏览器
|
| 1. 请求页面 (http://你的IP:8080)
↓
你的开发服务器
|
| 2. 返回页面 (index.html)
↓
同事的浏览器 (执行JS代码)
|
| 3. 发起同源请求 (http://你的IP:8080/api/user)
↓
你的开发服务器 (代理生效) 正常开发环境是没有这个的
|
| 4. 修改请求并转发 (https://api.company.com/user)
↓
真正的后端服务器
|
| 5. 返回数据
↓
你的开发服务器
|
| 6. 将数据返回给同事的浏览器
↓
同事的浏览器
|
| 7. 拿到数据,一切正常!
作用:代理(你的开发服务器)和后端服务器之间是服务器对服务器 的通信。服务器之间没有同源策略!
在现代前端工程化中,开发代理是必不可少的标准配置。它将 CORS 这个浏览器带来的限制,优雅地隔离在了开发环境内部,让前后端开发可以解耦,大大提高了效率。
如果不配置代理:
// 后端 CORS 配置(伪代码)
const allowedOrigins = [
'https://www.production-website.com', // 生产环境
'https://staging.company.com', // 测试环境
'http://localhost:3000', // 小明的开发环境
'http://localhost:8080', // 小红的开发环境
'http://192.168.1.105:3000', // 小刚的开发环境
// ... 新同事来了还得继续加
];
但是如果大家都用本地的开发服务器代理转发就很方便
本地的npm run dev 会启动vite,会充当代理服务器
但是!!!生产环境中:生产服务器返回已经构建好 的、静态的 index.html 和 JS 文件(机械地转发),这时候没有"开发服务器 vite"的说法,所以后端需要设置"生产白名单"!!!
让我们用一个比喻来理解
想象一下,你想给国外的朋友寄一封信(访问后端 API),但你不知道怎么处理国际邮资,而且你家门口的邮筒只收国内信件。
你(JS 代码):写好信,信封上写上"寄给:国外朋友,地址:XXX",然后把它投进家门口的邮筒(向 http://你的IP:8080/api/user 发起请求)。
小区邮局(你的开发服务器):邮递员(开发服务器)每天会来开这个邮筒。他看到你这封信,认出这是"国际信件"(匹配到了 /api 的代理规则)。
小区邮局(代理生效):邮递员并不会把你的信直接退回。他会:
换信封:把你的信装进一个国际信封,写上正确的国际邮资和回信地址(这就是 changeOrigin: true,修改 Origin 等请求头)。
改地址:在信封上写上真正的国际地址 https://api.company.com/user。
寄出去:通过国际邮政系统把信发出去(开发服务器向后端服务器发起新的请求)。
国外朋友(后端服务器):收到了信,回了一封信。
小区邮局:邮递员收到回信后,知道这是给你的,于是把它放进你家信箱。
你(浏览器):你从信箱里拿到了回信,你根本不知道中间发生了什么,只感觉"信寄出去了,回信也收到了"。
在这个比喻里:
你 = 浏览器 + JS 代码
小区邮局 = 你的开发服务器
邮递员 = 代理服务
CORS 的意义:
防御的是"跨站请求伪造"(CSRF/XSRF)
text
场景一:浏览器访问(有 CORS 限制)
用户操作:一个普通用户在浏览器里访问了 https://evil-hacker.com。
恶意脚本:这个网站里的 JavaScript 代码试图向你的后端 https://api.company.com 发起一个请求,窃取用户数据。
浏览器介入:浏览器看到这是一个跨域请求,就会自动发起 CORS 流程(预检请求等)。
服务器响应:你的后端服务器返回了响应头 Access-Control-Allow-Origin: https://www.your-frontend.com。
浏览器检查:浏览器检查发现,请求的来源是 https://evil-hacker.com,但服务器只允许 https://www.your-frontend.com 访问。
浏览器拦截:浏览器会拒绝将响应数据交给 evil-hacker.com 的脚本,并在控制台报出 CORS 错误。用户的数据得到了保护。
结论:CORS 成功阻止了恶意网站窃取数据。
api 工具没有限制,不过后端服务器可以 JWT,https,OAuth ,速率限制,授权等方式进行防御