詳解如何在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)頁(yè)的受限資源能夠被其他域名的頁(yè)面訪問(wèn)的一種機(jī)制。通過(guò)該機(jī)制,頁(yè)面能夠自由地使用不同源的圖片、樣式、腳本、iframes以及視頻。一些跨域的請(qǐng)求(特別是Ajax)常常會(huì)被同源策略(Same-origin policy)所禁止。跨源資源共享定義了一種方式,為的是瀏覽器和服務(wù)器之間能互相確認(rèn)是否足夠安全以至于能使用跨源請(qǐng)求(cross-origin requests)。比起純粹的同源請(qǐng)求,這將更為自由和功能性的(functionality),但比純粹的跨源請(qǐng)求更為安全。---維基百科
實(shí)現(xiàn)原理
跨域資源共享標(biāo)準(zhǔn)描述了,新的HTTP頭部在瀏覽器有權(quán)限的時(shí)候,應(yīng)該以如何的形式發(fā)送請(qǐng)求到遠(yuǎn)程URLs。雖然服務(wù)器會(huì)有一些校驗(yàn)和認(rèn)證,但是瀏覽器有責(zé)任去支持這些頭部以及增加相關(guān)的限制。對(duì)于能夠修改數(shù)據(jù)的Ajax和HTTP請(qǐng)求方法(特別是 GET 以外的 HTTP 請(qǐng)求,或者搭配某些 MIME 類型的 POST 請(qǐng)求),瀏覽器必須首先使用 OPTIONS 方法發(fā)起一個(gè)預(yù)檢請(qǐng)求(preflight request),從而獲知服務(wù)端是否允許該跨源請(qǐng)求。服務(wù)器確認(rèn)允許之后,才發(fā)起實(shí)際的 HTTP 請(qǐng)求。在預(yù)檢請(qǐng)求的返回中,服務(wù)器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認(rèn)證相關(guān)數(shù)據(jù))。
Go是如何實(shí)現(xiàn)
在Golang中,可以使用HTTP處理程序和中間件來(lái)實(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)行跨域請(qǐng)求
c.Writer.Header().Set("Access-Control-Allow-Origin", "http://mysite.vip")
// 允許特定的請(qǐng)求方法
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
// 允許特定的請(qǐng)求頭
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
// 允許攜帶身份憑證(如Cookie)
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
// 繼續(xù)處理請(qǐng)求
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)頭,指定允許跨域請(qǐng)求的域名。您可以根據(jù)需要設(shè)置為特定域名、通配符*(允許所有域名)或動(dòng)態(tài)獲取請(qǐng)求頭中的Origin值。另外,還設(shè)置了允許的請(qǐng)求方法、請(qǐng)求頭以及是否允許攜帶身份憑證(如Cookie)。
測(cè)試
這里通過(guò)命令行curl來(lái)驗(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的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang解析json數(shù)據(jù)的4種方法總結(jié)
在日常工作中每一名開(kāi)發(fā)者,不管是前端還是后端,都經(jīng)常使用 JSON,下面這篇文章主要給大家介紹了關(guān)于golang解析json數(shù)據(jù)的4種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
Golang連接PostgreSQL基本操作的實(shí)現(xiàn)
PostgreSQL是常見(jiàn)的免費(fèi)的大型關(guān)系型數(shù)據(jù)庫(kù),本文主要介紹了Golang連接PostgreSQL基本操作的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
詳解如何在Golang中監(jiān)聽(tīng)多個(gè)channel
這篇文章主要為大家詳細(xì)介紹了如何在Golang中實(shí)現(xiàn)監(jiān)聽(tīng)多個(gè)channel,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03
提升Golang應(yīng)用性能:深入理解Context的應(yīng)用
本文將深入探討如何通過(guò)深入理解和正確應(yīng)用Go語(yǔ)言中的Context來(lái)提升應(yīng)用性能。需要的朋友可以參考下2023-09-09

