欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、概述

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

要點:

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

二、簡單請求和預(yù)檢請求

簡單請求

1、判定條件

需要同時滿足以下條件,瀏覽器會認(rèn)為它是一個簡單請求

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

2、簡單請求交互

①當(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字段會告訴服務(wù)器,是哪個源地址在跨域請求

②服務(wù)器響應(yīng)頭中應(yīng)包含Access-Control-Allow-Origin ,當(dāng)服務(wù)器收到請求后,如果允許改請求跨域訪問,需要在響應(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ù)器允許自己訪問后,于是,它就把響應(yīng)順利的交給js

預(yù)檢請求

1、對于預(yù)檢請求,請求步驟如下:

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

2、步驟請求演示

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

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ù)檢請求

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ā)出的真實請求,請求中不包含響應(yīng)頭和也沒有消息體。

預(yù)檢請求特征:

請求方法為OPTIONS 沒有請求體

  • 請求頭中包含 Origin:請求的源,和簡單請求的含義一致
  • Access-Control-Request-Method:后續(xù)的真實請求將使用的請求方法
  • Access-Control-Request-Headers:后續(xù)的真實請求會改動的請求頭

②服務(wù)器允許

服務(wù)器收到預(yù)檢請求后,可以檢查預(yù)檢請求中包含的信息,如果允許這樣的請求,需要響應(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
...

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

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

③瀏覽器發(fā)送真實請求

預(yù)檢被服務(wù)器允許后,瀏覽器就會發(fā)送真實請求了,上面的代碼會發(fā)送下面的請求數(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)真實請求

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

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

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

1、安裝

使用命令安裝該中間件

go get github.com/gin-contrib/cors

2、函數(shù)

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

  • NEW方式

可以接收 CORS 中間件的配置項,可通過自定義配置項,滿足任意需要跨域的場景。

示例:
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ù)接收配置項,返回一個用戶自定義的 CORS 中間件,綁定到路由中。

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

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

1、安裝

使用命令安裝該中間件

go get github.com/gin-contrib/cors

2、函數(shù)

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

  • NEW方式

可以接收 CORS 中間件的配置項,可通過自定義配置項,滿足任意需要跨域的場景。

示例:
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ù)接收配置項,返回一個用戶自定義的 CORS 中間件,綁定到路由中。

配置項說明:

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

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

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  //獲取請求包的http請求方法
		origin := c.Request.Header.Get("Origin") //獲取請求包的head頭的Origin參數(shù)值
		var headerkeys []string
		for k := range c.Request.Header {
			headerkeys = append(headerkeys, k)
		}
		headerStr := strings.Join(headerkeys, ", ") //將請求包中head頭部分的參數(shù)用","連接成字符串
        //檢查請求頭不為空
		if headerStr != "" {
            //如果請求頭不為空,將請求頭的鍵名添加到一個字符串中,以便在設(shè)置響應(yīng)頭時包含這些鍵名。
			headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers,%s", headerStr)
		} else {
			headerStr = "access-control-allow-origin, access-control-allow-headers"
		}
        //檢查請求頭中origin是否為空
		if origin != "" {
            //設(shè)置響應(yīng)頭中的"Access-Control-Allow-Origin"字段,允許任何域名訪問資源(這是一個簡單的CORS策略,實際應(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")                                                                                                                                                           // 緩存請求信息 單位為秒
			c.Header("Access-Control-Allow-Credentials", "false")                                                                                                                                                  //  跨域請求是否需要帶cookie信息 默認(rèn)設(shè)置為true
			c.Set("content-type", "application/json")                                                                                                                                                              // 設(shè)置返回格式是json
		}
		//放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.JSON(http.StatusOK, "Options Request!")
		}
	}
}

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

相關(guān)文章

  • Golang指針隱式間接引用詳解

    Golang指針隱式間接引用詳解

    在 Go中,指針隱式解引用是指通過指針直接訪問指針?biāo)赶虻闹?,而不需要顯式地使用 * 運算符來解引用指針,這篇文章主要介紹了Golang指針隱式間接引用,需要的朋友可以參考下
    2023-05-05
  • Golang的Fork/Join實現(xiàn)代碼

    Golang的Fork/Join實現(xiàn)代碼

    Fork/Join本質(zhì)上是一種任務(wù)分解,將一個很大的任務(wù)分解成若干個小任務(wù),然后再對小任務(wù)進一步分解,直到最小顆粒度,然后并發(fā)執(zhí)行,對Golang的Fork/Join實現(xiàn)代碼感興趣的朋友跟隨小編一起看看吧
    2023-01-01
  • go語言vscode集成開發(fā)環(huán)境搭建

    go語言vscode集成開發(fā)環(huán)境搭建

    本文將介紹如何使用VSCode搭建Go語言開發(fā)環(huán)境,Go語言是一種簡潔高效的編程語言,而VSCode是一款輕量級的集成開發(fā)環(huán)境,二者的結(jié)合可以提供良好的開發(fā)體驗,
    2023-08-08
  • Golang Gorm實現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢

    Golang Gorm實現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢

    GORM 是一個流行的開源 ORM (Object-Relational Mapping) 庫,專為 Go 語言設(shè)計,它簡化了與 SQL 數(shù)據(jù)庫的交互,GORM 封裝了數(shù)據(jù)庫操作,使得開發(fā)者能夠通過簡單的鏈?zhǔn)秸{(diào)用來執(zhí)行 CRUD,本文給大家介紹了Golang Gorm實現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢,需要的朋友可以參考下
    2024-11-11
  • go mock模擬接口的實現(xiàn)

    go mock模擬接口的實現(xiàn)

    本文主要介紹了go mock模擬接口的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 詳解Golang中channel的實現(xiàn)

    詳解Golang中channel的實現(xiàn)

    channel俗稱管道,用于數(shù)據(jù)傳遞或數(shù)據(jù)共享,其本質(zhì)是一個先進先出的隊列,使用goroutine+channel進行數(shù)據(jù)通訊簡單高效,同時也線程安全,本文就給大家講講Golang中channel的實現(xiàn),需要的朋友可以參考下
    2023-09-09
  • Go語言框架快速集成限流中間件詳解

    Go語言框架快速集成限流中間件詳解

    這篇文章主要為大家介紹了Go語言框架快速集成限流中間件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Gin框架中參數(shù)校驗優(yōu)化詳解

    Gin框架中參數(shù)校驗優(yōu)化詳解

    這篇文章主要為大家詳細(xì)介紹了Gin框架中參數(shù)校驗優(yōu)化的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下
    2023-08-08
  • Go Println和Printf的區(qū)別詳解

    Go Println和Printf的區(qū)別詳解

    這篇文章主要介紹了Go Println和Printf的區(qū)別詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go中Context使用源碼解析

    Go中Context使用源碼解析

    這篇文章主要為大家介紹了Go中Context使用源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04

最新評論