CORS 入门笔记(前后端跨域)
很多刚学前后端的人:
第一次看到:
CORS error 跨域 Access-Control-Allow-Origin都会特别懵。
甚至:
会感觉:
明明后端接口没问题 为什么前端请求失败?其实:
问题不在后端逻辑。
而在:
浏览器安全机制一、什么是 CORS
CORS:
全称:
Cross-Origin Resource Sharing中文:
跨域资源共享一句话:
浏览器允许不同网站之间互相请求数据的规则二、为什么会有跨域
浏览器:
默认:
不允许不同源之间互相访问这是:
浏览器的同源策略三、什么是“同源”
必须:
这三个都一样:
协议 域名 端口才叫:
同源四、举例(重点)
这个算同源
http://localhost:3000 http://localhost:3000这个不算
端口不同:
http://localhost:3000 http://localhost:8080这个也不算
协议不同:
http://example.com https://example.com这个也不算
域名不同:
http://a.com http://b.com五、为什么浏览器要限制
因为:
如果不限制:
恶意网站:
可能:
偷偷请求你的银行接口非常危险。
六、最经典跨域场景
前端:
运行:
http://localhost:5173Vue/React 开发服务器。
后端
Gin:
运行:
http://localhost:8080前端请求后端
fetch("http://localhost:8080/user")七、结果
浏览器:
直接报错:
CORS error八、为什么 Postman 没问题
很多新人:
这里会懵。
Postman
不是浏览器。
没有:
同源策略所以:
不会拦截九、真正拦截的是谁
不是:
Gin也不是:
Go而是:
浏览器十、CORS 本质是什么
本质:
就是:
后端告诉浏览器: “我允许你跨域访问”十一、浏览器怎么知道允不允许
因为:
后端:
会返回:
响应头(Header)十二、最重要响应头(必须记住)
Access-Control-Allow-Origin十三、什么意思
例如:
Access-Control-Allow-Origin: *表示:
允许所有网站访问十四、Gin 如何解决 CORS
最简单:
使用中间件。
十五、安装 cors 中间件
go get github.com/gin-contrib/cors十六、最简单写法(重点)
packagemainimport("github.com/gin-contrib/cors""github.com/gin-gonic/gin")funcmain(){r:=gin.Default()// 开启 CORSr.Use(cors.Default())r.GET("/hello",func(c*gin.Context){c.JSON(200,gin.H{"msg":"hello",})})r.Run(":8080")}十七、这里到底发生了什么
r.Use(cors.Default())会自动:
给响应头加:
Access-Control-Allow-Origin: *于是:
浏览器:
发现:
后端允许跨域就不会拦截。
十八、完整请求流程(重点)
前端 fetch ↓ 浏览器发现跨域 ↓ 发送请求 ↓ Gin 返回 Header ↓ Access-Control-Allow-Origin ↓ 浏览器检查 ↓ 允许访问十九、前端为什么能收到数据了
因为:
浏览器:
看到:
后端允许跨域所以:
不再阻止。
二十、CORS 是浏览器安全机制
一定记住:
CORS 不是 Go 的规则 不是 Gin 的规则 不是 HTTP 的规则它是:
浏览器安全规则二十一、什么是预检请求(重点)
很多时候:
你会发现:
明明只发了一次请求 为什么后端收到两次?这就是:
预检请求(OPTIONS)二十二、什么时候会触发预检
例如:
PUT DELETE Authorization application/json这些:
可能触发:
OPTIONS 请求二十三、浏览器为什么要预检
浏览器:
会先问:
“后端允许吗?”二十四、流程图(重点)
浏览器 ↓ 先发 OPTIONS ↓ 后端返回允许 ↓ 浏览器再发真正请求二十五、为什么后端必须处理 OPTIONS
否则:
浏览器:
会认为:
不允许跨域二十六、cors.Default() 帮你做了什么
它会自动:
1. 处理 OPTIONS
2. 添加允许跨域 Header
3. 设置默认规则
所以:
非常方便。
二十七、自定义 CORS(重点)
真实项目:
一般:
不会:
允许所有网站二十八、自定义允许域名
r.Use(cors.New(cors.Config{AllowOrigins:[]string{"http://localhost:5173",},AllowMethods:[]string{"GET","POST","PUT","DELETE",},AllowHeaders:[]string{"Origin","Content-Type","Authorization",},}))二十九、AllowOrigins
表示:
允许哪些前端访问三十、AllowMethods
允许:
哪些 HTTP 方法。
三十一、AllowHeaders
允许:
哪些请求头。
例如:
AuthorizationJWT 登录:
经常会用。
三十二、JWT 为什么经常触发 CORS
因为:
JWT:
通常:
会带:
Authorization请求头。
于是:
浏览器:
会触发:
预检 OPTIONS三十三、为什么真实项目一定要配 CORS
因为:
前后端:
几乎:
都是分离的。
前端
localhost:5173后端
localhost:8080天然跨域。
三十四、最经典错误
1. 后端没开 CORS
浏览器直接拦截。
2. OPTIONS 没处理
预检失败。
3. Authorization 没允许
JWT 请求失败。
三十五、最后一句总结(必须记住)
CORS 本质:
浏览器的跨域安全机制核心思想:
后端通过 Header 告诉浏览器: “我允许你访问”Gin 最简单解决方案:
r.Use(cors.Default())真正核心流程:
前端请求 ↓ 浏览器检查是否跨域 ↓ 后端返回允许跨域 Header ↓ 浏览器决定是否放行