跨域中间件通俗理解

发布于:2025-07-15 ⋅ 阅读:(12) ⋅ 点赞:(0)
import (
    "github.com/gin-gonic/gin"
    "net/http"
)

// Cors 跨域处理
func Cors() gin.HandlerFunc {
    return func(c *gin.Context) {
        method := c.Request.Method
        c.Header("Access-Control-Allow-Origin", "*")
        c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
        c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")

        c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
        c.Header("Access-Control-Allow-Credentials", "true")
        // 放行所有OPTIONS方法
        if method == "OPTIONS" {
            c.AbortWithStatus(http.StatusNoContent)
        }
        // 处理请求
        c.Next()
    }
}

场景:小明家和保安大叔

想象一下:

  • 你的后端服务器:就是 小明家
  • 你的前端应用:是一个住在隔壁小区的 快递员
  • 浏览器(同源策略):是小明家小区门口非常负责任的 保安大叔

正常情况(同源)

如果小明自己点外卖,外卖员是小明小区的(比如小区里的便利店),保安大叔一看是自己人,直接放行。这就是同源,不需要复杂的检查。

跨域情况(不同源)

现在,那个隔壁小区的快递员(前端)要给小明家送一个包裹(API 请求)。

  1. 快递员来到门口:快递员到达小明家小区门口,被保安大叔(浏览器)拦下。
  2. 保安大叔的规则(同源策略):保安大叔的规定是:“不是我们小区的,一律不准进!” 这就是浏览器的同源策略,天生就不信任外来人员。

这时,快递员(前端)就懵了,包裹送不进去。

“预检请求”(OPTIONS)

快递员很聪明,他不对保安大叔说“我要进去”,而是先问:

  • 快递员(浏览器发送 OPTIONS 请求):“大叔,我不是来硬闯的。我就是想问问,我带着一个‘蓝色大包裹’(Content-Type: application/json),想用‘手推车’(POST 方法)送进去,你们家小明允许吗?”

这就是预检请求 (Preflight Request)。它不是真的在送东西,而是在投石问路。

Cors 中间件的作用

你的 Cors 中间件,就好比是小明提前给保安大叔写的一张“授权通知单”。这张通知单贴在了门卫室。

现在,我们来看看 middleware/cors.go 里的代码是怎么变成这张通知单的:

  • c.Header("Access-Control-Allow-Origin", "*")

    • 通知单内容:“允许 所有小区 的快递员给我家送东西。”
    • 通俗解释:告诉保安大叔,别管快递员是哪个小区的,都放行。
  • c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")

    • 通知单内容:“允许快递员用 手推车(POST)步行(GET) 或者只是 在门口问问(OPTIONS) 的方式送货。”
    • 通俗解释:告诉保安大叔,快递员用这几种方式送货都是可以的。
  • c.Header("Access-Control-Allow-Headers", "...")

    • 通知单内容:“允许快递员的包裹上贴有 ‘加急’(Authorization)‘易碎’(Content-Type) 等特殊标签。”
    • 通俗解释:告诉保安大叔,看到这些特殊标记的包裹,也是允许的。
  • if method == "OPTIONS" { c.AbortWithStatus(http.StatusNoContent) }

    • 保安大叔的行动:当保安大叔看到快递员只是在门口问问话(OPTIONS 请求),他会查阅墙上的“授权通知单”,然后对快递员挥挥手说:“问清楚了,没问题,你可以按你说的送了!” 然后就完事了。他不会再给小明打电话确认,因为通知单上写得很清楚了。这就直接结束了这次“询问”,效率很高。
  • c.Next()

    • 保安大叔的行动:当一个真正的包裹(比如一个 POST 请求)来了,保安大叔检查完通知单,确认一切符合规定后,就会打开大门,说:“进去吧!”。然后快递员才能继续往小明家走。c.Next() 就是“打开大门”这个动作,让请求能继续前进。

总结一下

为什么需要 Cors 函数?

因为你家小区的保安大叔(浏览器) 太负责了,默认不让任何外人进。你必须写一张授权通知单(Cors 中间件) 贴在门卫室,清楚地告诉保安大叔,什么样的外来人员(哪个前端地址)、用什么样的方式(POST/GET)、携带什么样的东西(请求头),是可以放行的。

没有这张通知单,所有来自外部的请求都会被保安大叔拒之门外。有了它,跨小区的合作才能顺利进行。


网站公告

今日签到

点亮在社区的每一天
去签到