Golang中使用gorilla处理CORS时Access-Control-Allow-Methods头缺失问题

Golang中使用gorilla处理CORS时Access-Control-Allow-Methods头缺失问题 我在使用 Gorilla handlers 的 CORS 功能时遇到了以下问题:

  1. 最大年龄值只能设置为 10 分钟,无法修改
  2. 没有按照我提供给 CORS 的所有方法发送 Access-Control-Allow-Methods 头部
  3. 没有按照我提供给 CORS 的所有头部发送 Access-Control-Allow-Headers 头部
	headersOk := handlers.AllowedHeaders([]string{"Authorization", "X-Requested-With"})
	originsOk := handlers.AllowedOrigins([]string{"localhost.com", "*"})
	methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
        log.Fatal(http.ListenAndServe(":8080", handlers.CORS(originsOk, methodsOk, headersOk, handlers.MaxAge(18600))(r)))

更多关于Golang中使用gorilla处理CORS时Access-Control-Allow-Methods头缺失问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中使用gorilla处理CORS时Access-Control-Allow-Methods头缺失问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中使用Gorilla handlers处理CORS时遇到Access-Control-Allow-Methods头缺失的问题,通常是由于配置方式或中间件顺序导致的。以下是解决方案和示例代码:

问题分析:

  1. MaxAge限制问题:Gorilla handlers的MaxAge默认有最大值限制
  2. 方法头缺失:可能是中间件配置顺序或浏览器预检请求处理问题
  3. 头部缺失:配置可能未正确应用

解决方案:

package main

import (
    "net/http"
    "time"
    
    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    
    // 配置CORS选项
    cors := handlers.CORS(
        handlers.AllowedOrigins([]string{"localhost.com", "*"}),
        handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"}),
        handlers.AllowedHeaders([]string{"Authorization", "X-Requested-With", "Content-Type"}),
        handlers.MaxAge(int(18600 * time.Second)), // 直接使用秒数
        handlers.AllowCredentials(),
    )
    
    // 应用CORS中间件
    handler := cors(r)
    
    // 注册路由
    r.HandleFunc("/api/test", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte(`{"message": "CORS test successful"}`))
    }).Methods("GET", "POST", "OPTIONS")
    
    // 启动服务器
    http.ListenAndServe(":8080", handler)
}

自定义CORS处理(如果上述方法仍有问题):

func customCORS(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 设置CORS头部
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, OPTIONS, DELETE, PATCH")
        w.Header().Set("Access-Control-Allow-Headers", "Authorization, X-Requested-With, Content-Type")
        w.Header().Set("Access-Control-Max-Age", "18600")
        
        // 处理预检请求
        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusOK)
            return
        }
        
        next.ServeHTTP(w, r)
    })
}

// 使用方式
func main() {
    r := mux.NewRouter()
    
    // 应用自定义CORS中间件
    handler := customCORS(r)
    
    r.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("CORS headers should be present"))
    })
    
    http.ListenAndServe(":8080", handler)
}

验证CORS头部的测试代码:

func testCORSHeaders() {
    req, _ := http.NewRequest("OPTIONS", "http://localhost:8080/api/test", nil)
    req.Header.Set("Origin", "http://localhost.com")
    req.Header.Set("Access-Control-Request-Method", "POST")
    
    rr := httptest.NewRecorder()
    handler := handlers.CORS(
        handlers.AllowedOrigins([]string{"localhost.com", "*"}),
        handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"}),
        handlers.AllowedHeaders([]string{"Authorization", "X-Requested-With"}),
    )(r)
    
    handler.ServeHTTP(rr, req)
    
    fmt.Printf("Access-Control-Allow-Methods: %s\n", rr.Header().Get("Access-Control-Allow-Methods"))
    fmt.Printf("Access-Control-Allow-Headers: %s\n", rr.Header().Get("Access-Control-Allow-Headers"))
    fmt.Printf("Access-Control-Max-Age: %s\n", rr.Header().Get("Access-Control-Max-Age"))
}

确保中间件配置正确,并且OPTIONS请求得到正确处理。如果问题仍然存在,建议检查Gorilla handlers的版本,并考虑使用更细粒度的CORS配置或自定义中间件实现。

回到顶部