在本文中,我们定义了CORS并展示了如何在Golang中使用CORS。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
同源政策
浏览器强制执行同源策略,该策略允许网页中的JS脚本访问其他网页中的数据,前提是两个网页都具有相同的来源。origin被定义为URL方案、主机名和端口号的组合。该策略有助于隔离潜在的恶意文档,减少可能的攻击媒介。
CORS
跨源资源共享(CORS)是一种基于HTTP标头的过程,它定义允许浏览器从哪些源加载资源。
CORS通过使用HTTPCORS标头放宽了同源策略。
请求标头:
- Origin-表示请求来源的服务器
- Access-Control-Request-Method-表示请求实现的HTTP方法的服务器
- Access-Control-Request-Headers-指示请求包含的标头的服务器
响应头:
- Access-Control-Allow-Origin-服务器允许的来源
- Access-Control-Allow-Methods-服务器允许的以逗号分隔的方法列表
- Access-Control-Allow-Headers-服务器允许的以逗号分隔的标头列表
- Access-Control-Expose-Headers-允许客户端访问的以逗号分隔的标头列表响应
- Access-Control-Max-Age-告诉浏览器缓存对预检请求的响应多长时间(以秒为单位)
- Access-Control-Allow-Credentials
GoCORS简单示例
在以下示例中,我们在Go服务器应用程序中启用CORS。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home</title> </head> <body> <script> async function doRequest() { let url = 'http://localhost:8080/hello'; let res = await fetch(url); if (res.ok) { let text = await res.text(); return text; } else { return `HTTP error: ${res.status}`; } } doRequest().then(data => { document.getElementById("output").innerText = data; }); </script> <div id="output"> </div> </body> </html>
在HTML网页中,我们使用JSFetchAPI来创建GET请求。该脚本读取响应并将其设置到输出div元素中。要尝试该示例,请通过网络服务器(例如nginx)或使用实时服务器VS代码扩展加载此网页。
package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/hello", HelloHandler) log.Println("Listening...") log.Fatal(http.ListenAndServe(":8080", nil)) } func HelloHandler(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5501") w.Header().Set("Access-Control-Max-Age", "15") fmt.Fprintf(w, "Hello, there!") }
在HelloHandler
中,我们为我们的服务器设置了CORS策略。
log.Fatal(http.ListenAndServe(":8080", nil))
该应用程序在本地主机上的8080端口上运行。要从其他来源访问此服务器的资源,必须启用它们。
w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5501") w.Header().Set("Access-Control-Max-Age", "15")
我们启用为此服务器设置CORS策略。http://127.0.0.1:5501
来源的JS脚本可以访问我们的资源。
转到CORS处理程序
github.com/rs/cors
是一个第三方包,它定义了在Golang中实现跨源资源共享W3规范的net/http处理程序。
package main import ( "fmt" "net/http" "github.com/rs/cors" ) func main() { mux := http.NewServeMux() cors := cors.New(cors.Options{ AllowedOrigins: []string{"*"}, AllowedMethods: []string{ http.MethodPost, http.MethodGet, }, AllowedHeaders: []string{"*"}, AllowCredentials: false, }) mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintln(w, "Hello there!") }) handler := cors.Handler(mux) http.ListenAndServe(":8080", handler) }
在示例中,我们使用github.com/rs/cors
为我们的服务器实现CORSpolicy。我们启用两种方法:GET和POST。使用*,我们允许allorigins。
EchoCORS示例
Echo、Gin或Fiber等Go网络框架具有支持CORS策略的现成中间件。
package main import ( "net/http" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) var ( words = []string{"kind", "warm", "cup", "coin", "blue"} ) func getWords(c echo.Context) error { return c.JSON(http.StatusOK, words) } func main() { e := echo.New() e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodDelete}, })) e.GET("/api/words", getWords) e.Logger.Fatal(e.Start(":8080")) }
该示例使用Echo框架中的CORS中间件。
在本教程中,我们在Go中使用了CORS。
列出所有Go教程。