update
This commit is contained in:
55
internal/middleware/cors.go
Normal file
55
internal/middleware/cors.go
Normal file
@ -0,0 +1,55 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"fashionapi/internal/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// CORS 跨域中间件,规则来自 yml 配置。
|
||||
//
|
||||
// allow_origins 为 ["*"] 时直接放行全部来源(与原项目行为一致);
|
||||
// 配置为具体域名列表时,仅当请求 Origin 命中白名单才回写该 Origin,
|
||||
// 这样生产环境可以收紧到指定域名而无需改代码。
|
||||
func CORS(cfg config.CORSConfig) gin.HandlerFunc {
|
||||
allowAll := len(cfg.AllowOrigins) == 0
|
||||
allowed := make(map[string]struct{}, len(cfg.AllowOrigins))
|
||||
for _, o := range cfg.AllowOrigins {
|
||||
if o == "*" {
|
||||
allowAll = true
|
||||
}
|
||||
allowed[o] = struct{}{}
|
||||
}
|
||||
|
||||
methods := strings.Join(cfg.AllowMethods, ", ")
|
||||
headers := strings.Join(cfg.AllowHeaders, ", ")
|
||||
maxAge := strconv.Itoa(cfg.MaxAge)
|
||||
|
||||
return func(c *gin.Context) {
|
||||
origin := c.GetHeader("Origin")
|
||||
switch {
|
||||
case allowAll:
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
case origin != "":
|
||||
if _, ok := allowed[origin]; ok {
|
||||
c.Header("Access-Control-Allow-Origin", origin)
|
||||
// 指定来源时必须声明 Vary,避免 CDN / 代理把响应错误地跨来源复用
|
||||
c.Header("Vary", "Origin")
|
||||
}
|
||||
}
|
||||
c.Header("Access-Control-Allow-Methods", methods)
|
||||
c.Header("Access-Control-Allow-Headers", headers)
|
||||
c.Header("Access-Control-Max-Age", maxAge)
|
||||
|
||||
// 预检请求直接结束,不进入业务逻辑
|
||||
if c.Request.Method == http.MethodOptions {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user