使用Go語(yǔ)言實(shí)現(xiàn)跨域資源共享(CORS)設(shè)置
如何使用Go語(yǔ)言進(jìn)行跨域資源共享(CORS)設(shè)置?
在Web開(kāi)發(fā)中,跨域資源共享(CORS)是一種重要的安全機(jī)制,它允許許多資源(例如字體、JavaScript等)在一個(gè)網(wǎng)頁(yè)上被另一個(gè)來(lái)源的網(wǎng)頁(yè)所訪問(wèn)。然而,出于安全考慮,瀏覽器默認(rèn)禁止這種跨域訪問(wèn)。為了解決這個(gè)問(wèn)題,我們可以使用Go語(yǔ)言來(lái)設(shè)置CORS。
為什么需要設(shè)置CORS?
在Web應(yīng)用中,我們經(jīng)常會(huì)遇到這樣的場(chǎng)景:一個(gè)網(wǎng)頁(yè)需要從另一個(gè)來(lái)源獲取資源,例如從CDN加載圖片或JavaScript文件,或者從一個(gè)API服務(wù)獲取數(shù)據(jù)。由于瀏覽器的同源策略限制,這些跨域請(qǐng)求默認(rèn)會(huì)被阻止。CORS機(jī)制就是為了解決這個(gè)問(wèn)題而設(shè)計(jì)的,它允許服務(wù)器明確指示哪些來(lái)源的網(wǎng)頁(yè)可以訪問(wèn)其資源。
如何使用Go語(yǔ)言設(shè)置CORS?
在Go語(yǔ)言中,設(shè)置CORS通常涉及到在HTTP響應(yīng)頭中設(shè)置適當(dāng)?shù)腃ORS相關(guān)頭信息。以下是一個(gè)簡(jiǎn)單的示例,展示了如何在Go的HTTP服務(wù)器中設(shè)置CORS:
package main
import (
"fmt"
"net/http"
)
func corsHandler(w http.ResponseWriter, r *http.Request) {
// 設(shè)置允許跨域訪問(wèn)的來(lái)源
w.Header().Set("Access-Control-Allow-Origin", "*")
// 設(shè)置允許的請(qǐng)求方法
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
// 設(shè)置允許的請(qǐng)求頭
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
// 預(yù)檢請(qǐng)求的緩存時(shí)間(秒)
w.Header().Set("Access-Control-Max-Age", "86400")
// 是否允許攜帶憑證
w.Header().Set("Access-Control-Allow-Credentials", "true")
// 處理實(shí)際的請(qǐng)求
// ...
}
func main() {
http.HandleFunc("/", corsHandler)
http.ListenAndServe(":8080", nil)
}
在這個(gè)示例中,我們定義了一個(gè)corsHandler函數(shù),它會(huì)在每個(gè)響應(yīng)中設(shè)置CORS相關(guān)的頭信息。然后,我們將這個(gè)函數(shù)注冊(cè)為處理根路徑(“/”)的處理器。
Access-Control-Allow-Origin:指定哪些來(lái)源的網(wǎng)頁(yè)可以訪問(wèn)該資源。在這個(gè)例子中,我們?cè)O(shè)置為"*",表示允許所有來(lái)源的訪問(wèn)。在實(shí)際應(yīng)用中,為了安全起見(jiàn),你應(yīng)該明確指定允許訪問(wèn)的來(lái)源。Access-Control-Allow-Methods:指定允許的HTTP請(qǐng)求方法,如GET、POST等。Access-Control-Allow-Headers:指定允許的請(qǐng)求頭。Access-Control-Max-Age:指定預(yù)檢請(qǐng)求的緩存時(shí)間(以秒為單位)。這可以減少不必要的預(yù)檢請(qǐng)求。Access-Control-Allow-Credentials:指定是否允許攜帶憑證(如cookies、HTTP認(rèn)證等)。
請(qǐng)注意,這只是一個(gè)簡(jiǎn)單的示例,用于說(shuō)明如何在Go語(yǔ)言中設(shè)置CORS。在實(shí)際應(yīng)用中,你可能需要根據(jù)具體需求進(jìn)行更復(fù)雜的配置。此外,你還可以考慮使用第三方庫(kù)(如gorilla/mux、chirouter等)來(lái)更方便地管理CORS設(shè)置。
拓展知識(shí):Go實(shí)現(xiàn)CORS(跨域)
實(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 類(lèi)型的 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!
到此這篇關(guān)于使用Go語(yǔ)言實(shí)現(xiàn)跨域資源共享(CORS)設(shè)置的文章就介紹到這了,更多相關(guān)Go設(shè)置CORS內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
GO語(yǔ)言開(kāi)發(fā)終端命令行小工具改進(jìn)更新
這篇文章主要為大家介紹了GO語(yǔ)言開(kāi)發(fā)終端命令行小工具的改進(jìn)更新,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Go如何實(shí)現(xiàn)HTTP請(qǐng)求限流示例
本篇文章主要介紹了Go如何實(shí)現(xiàn)HTTP請(qǐng)求限流示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
解決go語(yǔ)言ssh客戶端密碼過(guò)期問(wèn)題
這篇文章主要介紹了go語(yǔ)言ssh客戶端解決密碼過(guò)期問(wèn)題,本文給大家分享了解決的方法和原理,非常不錯(cuò),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Go語(yǔ)言的結(jié)構(gòu)體還能這么用?看這篇就夠了
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言結(jié)構(gòu)體的各個(gè)知識(shí)點(diǎn),最后還介紹了空結(jié)構(gòu)體的3種妙用。文中的示例代碼講解詳細(xì),希望對(duì)大家有所幫助2023-02-02
golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段
這篇文章主要介紹了golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
Golang?使用os?庫(kù)的?ReadFile()?讀文件最佳實(shí)踐
這篇文章主要介紹了Golang使用os庫(kù)的ReadFile()讀文件最佳實(shí)踐,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
go內(nèi)存隊(duì)列l(wèi)ist VS slice實(shí)現(xiàn)方式對(duì)比分析
這篇文章主要為大家介紹了go內(nèi)存隊(duì)列l(wèi)ist VS slice實(shí)現(xiàn)方式對(duì)比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
淺析Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作
這篇文章主要為大家詳細(xì)介紹了Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Go語(yǔ)言有一定的幫助,需要的可以跟隨小編一起學(xué)習(xí)一下2023-10-10

