golang轻松为API添加跨域资源共享功能的插件库CORS的使用

Golang轻松为API添加跨域资源共享功能的插件库CORS的使用

简介

CORS是一个net/http处理程序,实现了Golang中的跨域资源共享W3规范。

快速开始

安装Go并设置好GOPATH后,创建第一个.go文件,我们称之为server.go

package main

import (
    "net/http"

    "github.com/rs/cors"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte("{\"hello\": \"world\"}"))
    })

    // cors.Default() setup the middleware with default options being
    // all origins accepted with simple methods (GET, POST). See
    // documentation below for more options.
    handler := cors.Default().Handler(mux)
    http.ListenAndServe(":8080", handler)
}

安装cors库:

go get github.com/rs/cors

然后运行服务器:

go run server.go

服务器现在运行在localhost:8080上:

$ curl -D - -H 'Origin: http://foo.com' http://localhost:8080/
HTTP/1.1 200 OK
Access-Control-Allow-Origin: foo.com
Content-Type: application/json
Date: Sat, 25 Oct 2014 03:43:57 GMT
Content-Length: 18

{"hello": "world"}

参数配置

参数通过cors.New方法传递给中间件:

c := cors.New(cors.Options{
    AllowedOrigins: []string{"http://foo.com", "http://foo.com:8080"},
    AllowCredentials: true,
    // Enable Debugging for testing, consider disabling in production
    Debug: true,
})

// Insert the middleware
handler = c.Handler(handler)

可用参数:

  • AllowedOrigins []string: 允许跨域请求的源列表。如果包含特殊值*,则允许所有源。源可以包含通配符(*)。
  • AllowOriginFunc func (origin string) bool: 验证源的自定义函数。
  • AllowedMethods []string: 客户端允许使用的跨域请求方法。默认值是简单方法(GETPOST)。
  • AllowedHeaders []string: 客户端允许使用的非简单头部列表。
  • ExposedHeaders []string: 指示哪些头部可以安全地暴露给CORS API规范。
  • AllowCredentials bool: 指示请求是否可以包含用户凭据如cookies等。默认为false
  • MaxAge int: 预检请求结果可以缓存的时间(秒)。默认是0(不缓存)。
  • OptionsPassthrough bool: 让其他潜在的下一个处理程序处理OPTIONS方法。
  • OptionsSuccessStatus int: 用于成功OPTIONS请求的状态码。默认值是http.StatusNoContent(204)。
  • Debug bool: 调试标志,为服务器端CORS问题添加额外输出。

更多示例

// 更详细的配置示例
c := cors.New(cors.Options{
    AllowedOrigins: []string{"https://www.example.com", "http://localhost:3000"},
    AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
    AllowedHeaders: []string{"Accept", "Content-Type", "Authorization"},
    ExposedHeaders: []string{"Link"},
    AllowCredentials: false,
    MaxAge: 300,
})

性能基准

goos: darwin
goarch: arm64
pkg: github.com/rs/cors
BenchmarkWithout-10            135325480         8.124 ns/op       0 B/op       0 allocs/op
BenchmarkDefault-10            24082140        51.40 ns/op       0 B/op       0 allocs/op
BenchmarkAllowedOrigin-10      16424518        88.25 ns/op       0 B/op       0 allocs/op
BenchmarkPreflight-10          8010259       147.3 ns/op       0 B/op       0 allocs/op
BenchmarkPreflightHeader-10    6850962       175.0 ns/op       0 B/op       0 allocs/op

所有源代码均根据MIT许可证授权。


更多关于golang轻松为API添加跨域资源共享功能的插件库CORS的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang轻松为API添加跨域资源共享功能的插件库CORS的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang CORS 插件库使用指南

在开发API时,跨域资源共享(CORS)是一个常见需求。Golang中有多个优秀的库可以轻松实现CORS功能,下面我将介绍最常用的rs/cors库的使用方法。

安装

首先安装rs/cors库:

go get github.com/rs/cors

基本使用

package main

import (
	"net/http"
	
	"github.com/rs/cors"
)

func main() {
	// 创建路由器
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(`{"message": "Hello, CORS!"}`))
	})

	// 配置CORS中间件
	c := cors.New(cors.Options{
		AllowedOrigins:   []string{"http://localhost:3000", "http://example.com"},
		AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowedHeaders:   []string{"Accept", "Content-Type", "X-CSRF-Token"},
		ExposedHeaders:   []string{"Link"},
		AllowCredentials: true,
		MaxAge:           300, // 5分钟
	})

	// 使用CORS中间件包装路由器
	handler := c.Handler(mux)

	// 启动服务器
	http.ListenAndServe(":8080", handler)
}

配置选项详解

cors.Options结构体提供了丰富的配置选项:

  • AllowedOrigins: 允许的源列表,可以使用*表示允许所有源
  • AllowedMethods: 允许的HTTP方法
  • AllowedHeaders: 允许的请求头
  • ExposedHeaders: 允许浏览器访问的响应头
  • AllowCredentials: 是否允许发送凭据(cookies, HTTP认证等)
  • MaxAge: 预检请求的缓存时间(秒)
  • Debug: 是否开启调试模式

高级用法

1. 允许所有来源

c := cors.New(cors.Options{
    AllowedOrigins: []string{"*"},
    AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
})

2. 自定义来源检查

c := cors.New(cors.Options{
    AllowOriginFunc: func(origin string) bool {
        return origin == "http://trusted-domain.com" || 
               strings.HasSuffix(origin, ".trusted-subdomain.com")
    },
})

3. 与标准库集成

http.Handle("/", c.Handler(mux))
http.ListenAndServe(":8080", nil)

4. 与第三方路由器集成

// 使用Gin框架
router := gin.Default()
router.Use(func(c *gin.Context) {
    cors.New(cors.Options{
        AllowedOrigins: []string{"*"},
    }).HandlerFunc(c.Writer, c.Request)
    if c.Request.Method != "OPTIONS" {
        c.Next()
    } else {
        c.AbortWithStatus(204)
    }
})

处理预检请求

CORS中间件会自动处理OPTIONS方法的预检请求,你不需要手动处理。

常见问题

  1. 为什么我的CORS设置不生效?

    • 检查中间件是否正确地包装了处理器
    • 确保没有其他中间件修改了CORS头
    • 检查浏览器控制台错误信息
  2. 如何调试CORS问题?

    c := cors.New(cors.Options{
        Debug: true,
        // 其他配置...
    })
    

    开启调试模式会在控制台输出CORS相关信息

  3. 如何处理复杂请求?

    • 确保AllowedMethods包含所有需要的HTTP方法
    • 确保AllowedHeaders包含所有自定义请求头

替代方案

除了rs/cors,还有其他CORS库可供选择:

  1. github.com/gorilla/handlers中的CORS中间件
  2. github.com/gin-contrib/cors(专为Gin框架设计)

总结

使用rs/cors库可以轻松为Golang API添加CORS支持,只需几行代码就能处理各种跨域场景。根据实际需求调整配置选项,可以满足大多数Web应用的跨域需求。

记住在生产环境中不要简单地使用AllowedOrigins: []string{"*"},而应该明确指定允许的域名,以提高安全性。

回到顶部