最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用go語(yǔ)言實(shí)現(xiàn)cors中間件

 更新時(shí)間:2023年09月21日 09:44:08   作者:dayouziei  
CORS是一種瀏覽器安全機(jī)制,用于控制在Web應(yīng)用程序中不同源(Origin)之間的資源共享,本文將給大家介紹如何使用go語(yǔ)言實(shí)現(xiàn)cors中間件,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下

一、概述

CORS(Cross-Origin Resource Sharing)是一種瀏覽器安全機(jī)制,用于控制在Web應(yīng)用程序中不同源(Origin)之間的資源共享。一個(gè)源是由協(xié)議(例如http或https)、主機(jī)(例如 www.example.com)、以及端口(例如80或443)組成的組合。CORS允許服務(wù)器定義哪些源可以訪問(wèn)其資源,以及哪些HTTP方法和頭部可以在跨源請(qǐng)求中使用。

要點(diǎn):

  1. 同源策略(Same-Origin Policy):Web瀏覽器實(shí)施了同源策略,它限制了一個(gè)頁(yè)面中加載的資源只能來(lái)自相同的源,以防止而已站點(diǎn)獲取用戶的敏感信息。這意味著默認(rèn)情況下,跨域請(qǐng)求是被瀏覽器禁止的。
  2. 跨源HTTP請(qǐng)求:當(dāng)一個(gè)Web頁(yè)面需要從不同源的服務(wù)器獲取數(shù)據(jù)時(shí),例如通過(guò)AJAX請(qǐng)求或嵌入其他站點(diǎn)的資源(如字體、圖片或腳本),就會(huì)設(shè)計(jì)到跨源HTTP請(qǐng)求。
  3. CORS解決跨域問(wèn)題: CORS是一種機(jī)制,允許服務(wù)器在響應(yīng)中添加HTTP標(biāo)頭來(lái)指示瀏覽器允許跨域請(qǐng)求。這些標(biāo)頭包括”Access-Control-Allow-Origin“、”Access-Control-Allow-Methods“、”Access-Control-Allow-Headers“等
  4. 簡(jiǎn)單請(qǐng)求和預(yù)檢請(qǐng)求:瀏覽器將跨域HTTP請(qǐng)求分為兩種類型:簡(jiǎn)單請(qǐng)求(Simple Request)和預(yù)檢請(qǐng)求(Preflight Request)。簡(jiǎn)單請(qǐng)求就是常見(jiàn)的GET、POST請(qǐng)求,而預(yù)檢請(qǐng)求時(shí)一種用于檢查服務(wù)器是否支持某些請(qǐng)求的OPTION請(qǐng)求。
  5. 服務(wù)器配置:CORS的服務(wù)器配置通常在服務(wù)器端完成。服務(wù)器需要響應(yīng)OPTIONS請(qǐng)求并在響應(yīng)頭中包含CORS標(biāo)頭來(lái)指定允許的來(lái)源、HTTP方法和頭部。服務(wù)器還可以選擇性地要求攜帶憑據(jù)(credentials)
  6. 瀏覽器行為:瀏覽器在發(fā)送跨域請(qǐng)求時(shí)會(huì)自動(dòng)附加Origin頭,然后根據(jù)服務(wù)器的響應(yīng)判斷是否允許訪問(wèn)資源。如果CORS設(shè)置不正確,瀏覽器會(huì)阻止頁(yè)面訪問(wèn)響應(yīng)的數(shù)據(jù)。

二、簡(jiǎn)單請(qǐng)求和預(yù)檢請(qǐng)求

簡(jiǎn)單請(qǐng)求

1、判定條件

需要同時(shí)滿足以下條件,瀏覽器會(huì)認(rèn)為它是一個(gè)簡(jiǎn)單請(qǐng)求

  • 請(qǐng)求方法屬于其中一種:GET、POST、HEAD
  • 請(qǐng)求包僅包含安全的字段,常見(jiàn)字段:Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save-Data、Viewport-Width、Width
  • 請(qǐng)求頭如果包含Content-Type,僅限如下值:text/plain、multipart/form-data、application/x-www-form-urlencoded

2、簡(jiǎn)單請(qǐng)求交互

①當(dāng)瀏覽器判某個(gè)跨域請(qǐng)求時(shí)簡(jiǎn)單請(qǐng)求時(shí),會(huì)在請(qǐng)求頭中自動(dòng)添加Origin字段

GET /cors HTTP/1.1
Host: example.com
Connection: keep-alive
...
Referer: http://local.com/index.html
Origin: http://local.com //Origin字段會(huì)告訴服務(wù)器,是哪個(gè)源地址在跨域請(qǐng)求

②服務(wù)器響應(yīng)頭中應(yīng)包含Access-Control-Allow-Origin ,當(dāng)服務(wù)器收到請(qǐng)求后,如果允許改請(qǐng)求跨域訪問(wèn),需要在響應(yīng)頭中添加Access-Control-Allow-Origin字段

HTTP/1.1 200 OK
Date: Tue, 21 Jun 2023 08:03:35 GMT
...
Access-Control-Allow-Origin: http://local.com
...
消息體中的數(shù)據(jù)

當(dāng)瀏覽器看到服務(wù)器允許自己訪問(wèn)后,于是,它就把響應(yīng)順利的交給js

預(yù)檢請(qǐng)求

1、對(duì)于預(yù)檢請(qǐng)求,請(qǐng)求步驟如下:

  • 瀏覽器發(fā)送預(yù)檢請(qǐng)求,詢問(wèn)服務(wù)器是否允許
  • 服務(wù)器響應(yīng)是否允許
  • 瀏覽器發(fā)送真實(shí)請(qǐng)求
  • 服務(wù)器完成真實(shí)的響應(yīng)

2、步驟請(qǐng)求演示

要發(fā)送的請(qǐng)求包:

POST /cors HTTP/1.1

Host: example.com

Connection: keep-alive ...

Referer: http://local.com/index.html

Origin: http://local.com

{"name": "admin", "age": 20}

①瀏覽器發(fā)送預(yù)檢請(qǐng)求

OPTIONS /cors HTTP/1.1
Host: example.com
...
Origin: http://local.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: a, b, content-type

ps:這并非想要發(fā)出的真實(shí)請(qǐng)求,請(qǐng)求中不包含響應(yīng)頭和也沒(méi)有消息體。

預(yù)檢請(qǐng)求特征:

請(qǐng)求方法為OPTIONS 沒(méi)有請(qǐng)求體

  • 請(qǐng)求頭中包含 Origin:請(qǐng)求的源,和簡(jiǎn)單請(qǐng)求的含義一致
  • Access-Control-Request-Method:后續(xù)的真實(shí)請(qǐng)求將使用的請(qǐng)求方法
  • Access-Control-Request-Headers:后續(xù)的真實(shí)請(qǐng)求會(huì)改動(dòng)的請(qǐng)求頭

②服務(wù)器允許

服務(wù)器收到預(yù)檢請(qǐng)求后,可以檢查預(yù)檢請(qǐng)求中包含的信息,如果允許這樣的請(qǐng)求,需要響應(yīng)下面的消息格式

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: http://local.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: a, b, content-type
Access-Control-Max-Age: 86400
...

對(duì)于預(yù)檢請(qǐng)求,不需要響應(yīng)任何的消息體,只需要在響應(yīng)頭中添加: 

Access-Control-Allow-Origin:和簡(jiǎn)單請(qǐng)求一樣,表示允許的源 Access-Control-Allow-Methods:表示允許的后續(xù)真實(shí)的請(qǐng)求方法 Access-Control-Allow-Headers:表示允許改動(dòng)的請(qǐng)求頭 Access-Control-Max-Age:告訴瀏覽器,多少秒內(nèi),對(duì)于同樣的請(qǐng)求源、方法、頭,都不需要再發(fā)送預(yù)檢請(qǐng)求了

③瀏覽器發(fā)送真實(shí)請(qǐng)求

預(yù)檢被服務(wù)器允許后,瀏覽器就會(huì)發(fā)送真實(shí)請(qǐng)求了,上面的代碼會(huì)發(fā)送下面的請(qǐng)求數(shù)據(jù)

POST /cors HTTP/1.1
Host: example.com
Connection: keep-alive ...
Referer: http://local.com/index.html
Origin: http://local.com
{"name": "admin", "age": 20}

④服務(wù)器響應(yīng)真實(shí)請(qǐng)求

HTTP/1.1 200 OK
Date: Tue, 21 Jun 2023 08:03:35 GMT
...
Access-Control-Allow-Origin: http://local.com
...
添加用戶成功

三、使用go的gin框架實(shí)現(xiàn)cors配置

使用go的gin框架的話,說(shuō)白了就是添加一個(gè)中間件,Gin官方提供CORS中間件,可以很方便的使用 cors解決跨域問(wèn)題。

1、安裝

使用命令安裝該中間件

go get github.com/gin-contrib/cors

2、函數(shù)

cors中間件提供三個(gè)函數(shù),代表三種使用方式,分別是NEW、DefaultConfig、Default。

  • NEW方式

可以接收 CORS 中間件的配置項(xiàng),可通過(guò)自定義配置項(xiàng),滿足任意需要跨域的場(chǎng)景。

示例:
router.Use(cors.New(cors.Config{
    AllowOrigins:     []string{"https://foo.com"},
    AllowMethods:     []string{"PUT", "PATCH"},
    AllowHeaders:     []string{"Origin"},
    ExposeHeaders:    []string{"Content-Length"},
    AllowCredentials: true,
    AllowOriginFunc: func(origin string) bool {
      return origin == "https://github.com"
    },
    MaxAge: 12 * time.Hour,
  }))
//New 函數(shù)接收配置項(xiàng),返回一個(gè)用戶自定義的 CORS 中間件,綁定到路由中。

三、使用go的gin框架實(shí)現(xiàn)cors配置

使用go的gin框架的話,說(shuō)白了就是添加一個(gè)中間件,Gin官方提供CORS中間件,可以很方便的使用 cors解決跨域問(wèn)題。

1、安裝

使用命令安裝該中間件

go get github.com/gin-contrib/cors

2、函數(shù)

cors中間件提供三個(gè)函數(shù),代表三種使用方式,分別是NEW、DefaultConfigDefault。

  • NEW方式

可以接收 CORS 中間件的配置項(xiàng),可通過(guò)自定義配置項(xiàng),滿足任意需要跨域的場(chǎng)景。

示例:
router.Use(cors.New(cors.Config{
    AllowOrigins:     []string{"https://foo.com"},
    AllowMethods:     []string{"PUT", "PATCH"},
    AllowHeaders:     []string{"Origin"},
    ExposeHeaders:    []string{"Content-Length"},
    AllowCredentials: true,
    AllowOriginFunc: func(origin string) bool {
      return origin == "https://github.com"
    },
    MaxAge: 12 * time.Hour,
  }))
//New 函數(shù)接收配置項(xiàng),返回一個(gè)用戶自定義的 CORS 中間件,綁定到路由中。

配置項(xiàng)說(shuō)明:

  • AllowAllOrigins bool 允許所有請(qǐng)求源。
  • AllowOrigins []string 指定允許請(qǐng)求源的列表,如果列表中存在 *,則允許所有請(qǐng)求源,默認(rèn)值是 []。
  • AllowOriginFunc func(origin string) bool 接收參數(shù) origin,函數(shù)體中的驗(yàn)證邏輯返回是否允許跨域請(qǐng)求。該配置項(xiàng)優(yōu)先級(jí)高于 AllowOrigins []string,如果設(shè)置該配置項(xiàng),AllowOrigins []string 配置項(xiàng)的設(shè)置被忽略。
  • AllowMethods []string 允許的請(qǐng)求方式,默認(rèn)值是 GET,POSTPUT,PATCH,DELETE,HEAD,和 OPTIONS。
  • AllowHeaders []string 用在對(duì)預(yù)請(qǐng)求的響應(yīng)中,指示實(shí)際的請(qǐng)求中可以使用哪些 HTTP 請(qǐng)求頭。
  • AllowCredentials bool 表示請(qǐng)求附帶請(qǐng)求憑據(jù)時(shí)是否響應(yīng)請(qǐng)求,例如 cookie、HTTP authentication 或客戶端 SSL 證書(shū)。
  • ExposeHeaders []string 可以在響應(yīng)中顯示的請(qǐng)求頭。
  • MaxAge time.Duration 指示預(yù)請(qǐng)求的結(jié)果能被緩存多久。
  • AllowWildcard bool 添加請(qǐng)求源是否允許使用通配符,例如 http://some-domain/*https://api. 或 http://some.*.subdomain.com。
  • AllowBrowserExtensions bool 允許使用常用的瀏覽器的擴(kuò)展模式。
  • AllowWebSockets bool 允許使用 WebSocket 協(xié)議。
  • AllowFiles bool 允許使用 file:// 協(xié)議。
  • DefaultConfig方式

默認(rèn)設(shè)置一些通用配置項(xiàng),我們可以直接使用,也可以在此基礎(chǔ)上添加我們需要的其他配置項(xiàng)。

func Default() gin.HandlerFunc {
 config := DefaultConfig()
 config.AllowAllOrigins = true
 return New(config)
}

3、某段配置代碼分析

//設(shè)置cors中間件
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method  //獲取請(qǐng)求包的http請(qǐng)求方法
		origin := c.Request.Header.Get("Origin") //獲取請(qǐng)求包的head頭的Origin參數(shù)值
		var headerkeys []string
		for k := range c.Request.Header {
			headerkeys = append(headerkeys, k)
		}
		headerStr := strings.Join(headerkeys, ", ") //將請(qǐng)求包中head頭部分的參數(shù)用","連接成字符串
        //檢查請(qǐng)求頭不為空
		if headerStr != "" {
            //如果請(qǐng)求頭不為空,將請(qǐng)求頭的鍵名添加到一個(gè)字符串中,以便在設(shè)置響應(yīng)頭時(shí)包含這些鍵名。
			headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers,%s", headerStr)
		} else {
			headerStr = "access-control-allow-origin, access-control-allow-headers"
		}
        //檢查請(qǐng)求頭中origin是否為空
		if origin != "" {
            //設(shè)置響應(yīng)頭中的"Access-Control-Allow-Origin"字段,允許任何域名訪問(wèn)資源(這是一個(gè)簡(jiǎn)單的CORS策略,實(shí)際應(yīng)用中可能需要更嚴(yán)格的控制)。
			c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
			c.Header("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE, UPDATE")
			c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
			c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域關(guān)鍵設(shè)置 讓瀏覽器可以解析
			c.Header("Access-Control-Max-Age", "172800")                                                                                                                                                           // 緩存請(qǐng)求信息 單位為秒
			c.Header("Access-Control-Allow-Credentials", "false")                                                                                                                                                  //  跨域請(qǐng)求是否需要帶cookie信息 默認(rèn)設(shè)置為true
			c.Set("content-type", "application/json")                                                                                                                                                              // 設(shè)置返回格式是json
		}
		//放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.JSON(http.StatusOK, "Options Request!")
		}
	}
}

以上就是使用go語(yǔ)言實(shí)現(xiàn)cors中間件的詳細(xì)內(nèi)容,更多關(guān)于go實(shí)現(xiàn)cors中間件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go系列教程之反射的用法

    Go系列教程之反射的用法

    這篇文章主要介紹了Go系列教程之反射的用法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Golang中Error的設(shè)計(jì)與實(shí)踐詳解

    Golang中Error的設(shè)計(jì)與實(shí)踐詳解

    這篇文章主要為大家詳細(xì)介紹了Golang中Error的設(shè)計(jì)以及是具體如何處理錯(cuò)誤的相關(guān)知識(shí),文中的示例代碼簡(jiǎn)潔易懂,需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08
  • Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之選擇排序示例詳解

    Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之選擇排序示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之選擇排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 關(guān)于go-zero服務(wù)自動(dòng)收集問(wèn)題分析

    關(guān)于go-zero服務(wù)自動(dòng)收集問(wèn)題分析

    這篇文章主要介紹了關(guān)于go-zero服務(wù)自動(dòng)收集問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Go中RPC遠(yuǎn)程過(guò)程調(diào)用的實(shí)現(xiàn)

    Go中RPC遠(yuǎn)程過(guò)程調(diào)用的實(shí)現(xiàn)

    本文主要介紹了Go中RPC遠(yuǎn)程過(guò)程調(diào)用的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 基于Go語(yǔ)言實(shí)現(xiàn)猜謎游戲

    基于Go語(yǔ)言實(shí)現(xiàn)猜謎游戲

    這篇文章主要為大家詳細(xì)介紹了如何基于Go語(yǔ)言實(shí)現(xiàn)猜謎游戲,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)
    2023-09-09
  • Go語(yǔ)言學(xué)習(xí)之接口類型(interface)詳解

    Go語(yǔ)言學(xué)習(xí)之接口類型(interface)詳解

    接口是用來(lái)定義行為的類型,定義的行為不由接口直接實(shí)現(xiàn),而由通過(guò)方法由定義的類型實(shí)現(xiàn),本文就來(lái)和大家詳細(xì)講講Go語(yǔ)言中接口的使用吧
    2023-03-03
  • 詳解Golang如何實(shí)現(xiàn)支持隨機(jī)刪除元素的堆

    詳解Golang如何實(shí)現(xiàn)支持隨機(jī)刪除元素的堆

    堆是一種非常常用的數(shù)據(jù)結(jié)構(gòu),它能夠支持在O(1)的時(shí)間復(fù)雜度獲取到最大值(或最小值)。本文主要介紹了如何實(shí)現(xiàn)支持O(log(n))隨機(jī)刪除元素的堆,需要的可以參考一下
    2022-09-09
  • 淺析Golang開(kāi)發(fā)中g(shù)oroutine的正確使用姿勢(shì)

    淺析Golang開(kāi)發(fā)中g(shù)oroutine的正確使用姿勢(shì)

    很多初級(jí)的Gopher在學(xué)習(xí)了goroutine之后,在項(xiàng)目中其實(shí)使用率不高,所以這篇文章小編主要來(lái)帶大家深入了解一下goroutine的常見(jiàn)使用方法,希望對(duì)大家有所幫助
    2024-03-03
  • Go語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)解析JSON數(shù)據(jù)的多種方式

    Go語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)解析JSON數(shù)據(jù)的多種方式

    本文主要介紹了Go語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)解析JSON數(shù)據(jù)的多種方式,包括map[string]interface{}、interface{}、json.RawMessage及第三方庫(kù)gjson/mapstructure,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-05-05

最新評(píng)論

阳东县| 阳曲县| 健康| 麟游县| 铜陵市| 抚州市| 北辰区| 三原县| 九江市| 漠河县| 剑河县| 恩平市| 方山县| 文登市| 内江市| 长兴县| 元江| 驻马店市| 甘肃省| 沅陵县| 凤山县| 剑河县| 宁陕县| 临城县| 浙江省| 泰顺县| 东台市| 会昌县| 剑河县| 贵州省| 竹山县| 怀宁县| 玉树县| 丹寨县| 郧西县| 霍林郭勒市| 玉林市| 正阳县| 建阳市| 民权县| 云梦县|