Go语言实现的CORS跨域资源共享解决方案

发表时间: 2020-06-13 17:55

在当前主流的前后端分离中,CORS(跨域资源共享)请求问题是往往需要由 Web 后端来解决。而 Go 语言在 Web 开发领域日渐发展,自然也需要一个处理跨域问题的库。CORS 库,就是我们所需要的。

CORS跨域资源共享

简介

CORS,准确的说是 github.com/rs/cors 库,是在 Github 上由 rs 开源的处理 HTTP 跨域的中间件,项目仓库在
https://github.com/rs/cors,目前版本为 1.7.0。CORS 库为 net/http 服务器的 Handler 添加了跨域处理逻辑,是一个非常方便的 Go 语言 Web 开发中解决跨域问题的方案。

Golang CORS

安装

CORS 使用 go get 安装:

go get github.com/rs/cors

当 CORS 库与 net/http 共同使用时,其没有额外依赖。另外,CORS 库还提供了对于 gin 框架的中间件实现,此时需要 gin 框架的依赖,引用的库为
github.com/rs/cors/wrapper/gin。

示例

CORS 库的主要接口是结构体 Cors,通过实例化 Cors 作为一个中间件,为 net/http 的 Handler 添加跨域功能。一个基本的使用例子如下:

package mainimport (    "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\"}"))    })    handler := cors.Default().Handler(mux)  // CORS中间件    http.ListenAndServe(":8080", handler)}

运行服务器后,进行跨域请求,

curl -D - -H 'Origin: http://foo.com' http://localhost:8080/

返回 200 OK,跨域问题解决。

cors.Default 使用默认配置生成了一个 Cors 实例,并使用了 Handler 方法,把跨域规范作用到请求上,且添加必要的跨域 HTTP 消息头。Cors 的 Handler 方法接受和返回的都是一个 http.Handler:

func (c *Cors) Handler(h http.Handler) http.Handler

cors.Default 所产生的默认配置为:允许 GET 和 POST 方法对于所有请求来源(*)的请求,且不允许请求包含用户凭证信息(如 Cookie,HTTP 验证和客户端 SSL 证书等)。

如果想要进行进一步定制,可以使用 cors.New 来自定义,参数由 cors.Options 结构定义,它包括以下参数:

  • AllowedOrigins:跨域请求来源列表,默认为通配符 *;
  • AllowOriginFunc:跨域请求验证函数,接受请求来源并返回布尔值;
  • AllowOriginRequestFun:跨域请求验证函数,接受 http.Request 和请求来源;
  • AllowedMethods:允许跨域的 HTTP 请求方法列表,默认为 GET 和 POST;
  • AllowedHeaders:跨域请求中所允许的消息头列表;
  • ExposedHeaders:允许暴露给 CORS 接口的消息头列表;
  • MaxAge:请求的最长缓存时间;
  • AllowCredentials:是否允许请求包含用户凭证信息,默认为否;
  • OptionsPassthrough:是否处理方法为 OPTIONS 的请求;
  • Debug:是否设置为调试模式。

CORS跨域

更多

CORS 库提供了包括 net/http、Goji、Martini、Negroni、Alice、HttpRouter、Gorilla、Buffalo、Gin 和 Chi 在内的 Go 语言 Web 框架的使用例子,各框架的开发者均可以进行参考使用。

总结

CORS 库为 Go 语言的 Web 开发解决了跨域问题,是一个非常实用的中间件,可以应用到各种 Web 框架之中去。

CORS 库代码量不大,文档清晰,例子丰富,还进行了详尽的测试和性能评估,是一个 HTTP 服务器中间件的优秀例子,值得学习。