詳解如何在Golang中實(shí)現(xiàn)CORS(跨域)
什么是跨域
如果兩個(gè) URL 的協(xié)議、端口(如果有指定的話)和主機(jī)都相同的話,則這兩個(gè) URL 是同源的。例如
URL | 結(jié)果 | 原因 | |
---|---|---|---|
http://store.company.com/dir2/other.html | 同源 | 只有路徑不同 | |
http://store.company.com/dir/inner/another.html | 同源 | 只有路徑不同 | |
https://store.company.com/secure.html | 失敗 | 協(xié)議不同 | |
http://store.company.com:81/dir/etc.html | 失敗 | 端口不同(http:// 默認(rèn)端口是 80) | |
http://store.company.com:81/dir/etc.html | 失敗 | 主機(jī)不同 |
什么是CORS
跨域資源共享(Cross-origin resource sharing,CORS),用于讓網(wǎng)頁的受限資源能夠被其他域名的頁面訪問的一種機(jī)制。通過該機(jī)制,頁面能夠自由地使用不同源的圖片、樣式、腳本、iframes以及視頻。一些跨域的請求(特別是Ajax)常常會(huì)被同源策略(Same-origin policy)所禁止??缭促Y源共享定義了一種方式,為的是瀏覽器和服務(wù)器之間能互相確認(rèn)是否足夠安全以至于能使用跨源請求(cross-origin requests)。比起純粹的同源請求,這將更為自由和功能性的(functionality),但比純粹的跨源請求更為安全。---維基百科
實(shí)現(xiàn)原理
跨域資源共享標(biāo)準(zhǔn)描述了,新的HTTP頭部在瀏覽器有權(quán)限的時(shí)候,應(yīng)該以如何的形式發(fā)送請求到遠(yuǎn)程URLs。雖然服務(wù)器會(huì)有一些校驗(yàn)和認(rèn)證,但是瀏覽器有責(zé)任去支持這些頭部以及增加相關(guān)的限制。對于能夠修改數(shù)據(jù)的Ajax和HTTP請求方法(特別是 GET 以外的 HTTP 請求,或者搭配某些 MIME 類型的 POST 請求),瀏覽器必須首先使用 OPTIONS 方法發(fā)起一個(gè)預(yù)檢請求(preflight request),從而獲知服務(wù)端是否允許該跨源請求。服務(wù)器確認(rèn)允許之后,才發(fā)起實(shí)際的 HTTP 請求。在預(yù)檢請求的返回中,服務(wù)器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認(rèn)證相關(guān)數(shù)據(jù))。
Go是如何實(shí)現(xiàn)
在Golang中,可以使用HTTP處理程序和中間件來實(shí)現(xiàn)CORS。接著我們以Gin為例
package main import ( "github.com/gin-gonic/gin" "net/http" ) func main() { router := gin.Default() // CORS中間件 cors := func(c *gin.Context) { // 允許特定的域進(jìn)行跨域請求 c.Writer.Header().Set("Access-Control-Allow-Origin", "http://mysite.vip") // 允許特定的請求方法 c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE") // 允許特定的請求頭 c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") // 允許攜帶身份憑證(如Cookie) c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") // 繼續(xù)處理請求 c.Next() } // 應(yīng)用CORS中間件到所有路由 router.Use(cors) // 定義一個(gè)路由和處理器函數(shù) router.GET("/hello-world", func(c *gin.Context) { c.String(http.StatusOK, "Hello, World!") }) router.Run(":8080") }
輸出
[GIN-debug] GET /hello-world --> main.main.func2 (4 handlers)
[GIN-debug] Listening and serving HTTP on :8080
在上例中,設(shè)置了Access-Control-Allow-Origin響應(yīng)頭,指定允許跨域請求的域名。您可以根據(jù)需要設(shè)置為特定域名、通配符*(允許所有域名)或動(dòng)態(tài)獲取請求頭中的Origin值。另外,還設(shè)置了允許的請求方法、請求頭以及是否允許攜帶身份憑證(如Cookie)。
測試
這里通過命令行curl來驗(yàn)證,如果返回結(jié)果中出現(xiàn) CORS 相關(guān)的 header( ccess-Control-Allow-Origin: * < Access-Control-Allow-Methods: * < Access-Control-Allow-Headers: * < Access-Control-Expose-Headers: * < Access-Control-Max-Age: 5 ),則跨域成功。結(jié)果如下:
#curl -i -k http://127.0.0.1:8080/hello-world HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Origin: http://mysite.vip Content-Type: text/plain; charset=utf-8 Date: Sat, 14 Oct 2023 13:42:35 GMT Content-Length: 13 Hello, World!
Success
以上就是詳解如何在Golang中實(shí)現(xiàn)CORS(跨域)的詳細(xì)內(nèi)容,更多關(guān)于Golang實(shí)現(xiàn)CORS的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang解析json數(shù)據(jù)的4種方法總結(jié)
在日常工作中每一名開發(fā)者,不管是前端還是后端,都經(jīng)常使用 JSON,下面這篇文章主要給大家介紹了關(guān)于golang解析json數(shù)據(jù)的4種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06Golang連接PostgreSQL基本操作的實(shí)現(xiàn)
PostgreSQL是常見的免費(fèi)的大型關(guān)系型數(shù)據(jù)庫,本文主要介紹了Golang連接PostgreSQL基本操作的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02詳解如何在Golang中監(jiān)聽多個(gè)channel
這篇文章主要為大家詳細(xì)介紹了如何在Golang中實(shí)現(xiàn)監(jiān)聽多個(gè)channel,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03提升Golang應(yīng)用性能:深入理解Context的應(yīng)用
本文將深入探討如何通過深入理解和正確應(yīng)用Go語言中的Context來提升應(yīng)用性能。需要的朋友可以參考下2023-09-09