CORS 跨域:中间件配置要点

前后端分离后,浏览器页面(http://web.example.com)直接请求 API(http://api.example.com)会触发跨域限制。GoFrame v2 的跨域能力由 ghttp.Response 上的 CORS 方法与路由中间件配合完成,官方文档“CORS 跨域处理”章节给出了完整配置范式。

基本概念

  • CORS(跨域资源共享)是 W3C 标准:服务端通过响应头声明“允许哪些来源、哪些方法/请求头、是否允许携带凭证”。
  • ghttp 用 CORSOptions 对象承载这些选项,Response 提供 CORS(options)CORSDefault()DefaultCORSOptions()CORSAllowedOrigin(options) 方法。
  • OPTIONS 预检请求由 Server 按规范自动响应,前提是请求走到了带 CORS 头的路由。

通过中间件放行跨域

把跨域配置写成中间件挂在路由分组上,是最常见、最清晰的形态。先看“全放行”版:

package main

import (
    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/net/ghttp"
)

// 允许跨域请求的中间件:使用默认选项
func MiddlewareCORS(r *ghttp.Request) {
    r.Response.CORSDefault()
    r.Middleware.Next()
}

func main() {
    s := g.Server()
    s.Group("/api.v1", func(group *ghttp.RouterGroup) {
        group.Middleware(MiddlewareCORS)
        group.GET("/order", func(r *ghttp.Request) {
            r.Response.Write("GET")
        })
    })
    s.SetPort(8199)
    s.Run()
}

group.Middleware 对分组下所有路由生效(含子路由),CORSDefault() 使用框架默认选项,适合开放接口或开发环境。

限制来源:只信任自己的域名

生产环境几乎都要收敛来源。利用 DefaultCORSOptions() 取出默认值后修改 AllowDomain,再交给 CORS

func MiddlewareCORS(r *ghttp.Request) {
    corsOptions := r.Response.DefaultCORSOptions()
    corsOptions.AllowDomain = []string{"example.com", "admin.example.com"} // 白名单域名
    if !r.Response.CORSAllowedOrigin(corsOptions) {
        r.Response.WriteStatus(http.StatusForbidden) // 来源不在白名单,直接拒绝
        return
    }
    r.Response.CORS(corsOptions)
    r.Middleware.Next()
}

CORSAllowedOrigin 在真正放行前先校验当前请求的 Origin,来源不合法时业务逻辑根本不会执行,比“先放行再判断”更省资源也更安全。

注意点

  • 携带 Cookie 的跨域请求需要 AllowCredentials 配合精确的 AllowOrigin(不能简单用通配 *),前端也要设置 withCredentials
  • 不要对全站一刀切放开 *:把 CORS 中间件只挂到需要跨域的 API 分组即可。
  • 跨域也常与 WebSocket 场景相关,官方说明允许 WebSocket 跨域同样通过 CORS 方式处理;但 WebSocket 本身的来源/鉴权校验仍需业务层自己完成。
  • 若用规范路由(group.Bind),同样把 CORS 中间件挂到分组上,文档与跨域可并存。

小结

CORS 的落地公式:中间件 + 分组路由 + CORSOptions。开发期用 CORSDefault() 快速放行,生产期用 AllowDomain 白名单并用 CORSAllowedOrigin 提前拦截。默认选项字段(AllowMethods/AllowHeaders/MaxAge 等)可继续按需调整,细节以官方文档 goframe.org 为准。

笔记加载中…