亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

在Gin框架中解決跨域問(wèn)題的多種方法

 更新時(shí)間:2024年10月28日 09:05:54   作者:景天科技苑  
在使用Go語(yǔ)言進(jìn)行Web開(kāi)發(fā)時(shí),Gin框架因其簡(jiǎn)潔、高效的特點(diǎn)而被廣泛使用,然而,在實(shí)際開(kāi)發(fā)中,跨域問(wèn)題(CORS, Cross-Origin Resource Sharing)是一個(gè)常見(jiàn)的挑戰(zhàn),本文將結(jié)合實(shí)際案例,詳細(xì)介紹在Gin框架中解決跨域問(wèn)題的多種方法,需要的朋友可以參考下

一、引言

在使用Go語(yǔ)言進(jìn)行Web開(kāi)發(fā)時(shí),Gin框架因其簡(jiǎn)潔、高效的特點(diǎn)而被廣泛使用。然而,在實(shí)際開(kāi)發(fā)中,跨域問(wèn)題(CORS, Cross-Origin Resource Sharing)是一個(gè)常見(jiàn)的挑戰(zhàn)。跨域問(wèn)題主要源于瀏覽器的同源策略(Same-Origin Policy),當(dāng)一個(gè)網(wǎng)頁(yè)嘗試從不同的源(協(xié)議、域名或端口不同)請(qǐng)求資源時(shí),就會(huì)產(chǎn)生跨域問(wèn)題。本文將結(jié)合實(shí)際案例,詳細(xì)介紹在Gin框架中解決跨域問(wèn)題的多種方法。

二、跨域問(wèn)題的基本概念

1. 同源策略

同源策略是瀏覽器的一種安全機(jī)制,用于限制一個(gè)源(協(xié)議、域名和端口)的文檔或腳本如何與另一個(gè)源的資源進(jìn)行交互。例如,一個(gè)在http://example.com上的網(wǎng)頁(yè)不能從http://otherdomain.com加載數(shù)據(jù),即使服務(wù)器響應(yīng)了請(qǐng)求,瀏覽器也會(huì)阻止該請(qǐng)求返回的數(shù)據(jù)被腳本訪問(wèn)。

同源策略,是瀏覽器為了保護(hù)用戶信息安全的一種安全機(jī)制。所謂的同源就是指代通信的兩個(gè)地址(例如服務(wù)端接口地址與瀏覽器客戶端頁(yè)面地址)之間比較,是否協(xié)議、域名和端口相同。不同源的客戶端腳本[javascript]在沒(méi)有明確授權(quán)的情況下,沒(méi)有權(quán)限讀寫(xiě)對(duì)方信息。

同源策略機(jī)制(Same Origin Policy,SOP)是一種約定,它是瀏覽器最核心也是最基本的安全功能,如果缺少了同源策略。則瀏覽器的正常功能可能都會(huì)受到影響??梢哉f(shuō)Web是構(gòu)建在同源策略基礎(chǔ)上的,瀏覽器只是針對(duì)同源策略的一種實(shí)現(xiàn)。

當(dāng)一個(gè)瀏覽器的兩個(gè)tab頁(yè)中分別打開(kāi)百度和谷歌的頁(yè)面時(shí),當(dāng)瀏覽器的百度tab頁(yè)執(zhí)行一個(gè)腳本的時(shí)候會(huì)檢查這個(gè)腳本是屬于哪個(gè)頁(yè)面的,即檢查是否同源,只有和百度同源的腳本才會(huì)被執(zhí)行。如果非同源,那么在請(qǐng)求數(shù)據(jù)時(shí),瀏覽器會(huì)在控制臺(tái)中報(bào)一個(gè)異常,提示拒絕訪問(wèn)。不同源的客戶端腳本在沒(méi)有明確授權(quán)的情況下,不能讀寫(xiě)對(duì)方資源。所以google.com下的js腳本采用ajax讀取baidu.com里面的文件數(shù)據(jù)是會(huì)報(bào)錯(cuò)的。

跨域請(qǐng)求,首先瀏覽器為了安全,做了一個(gè)同源策略機(jī)制,也就是所謂的同源安全策略,本質(zhì)上,其實(shí)是不存在所謂的跨不跨域的,把瀏覽器想象成一個(gè)發(fā)送網(wǎng)絡(luò)請(qǐng)求的軟件,按照道理來(lái)說(shuō),請(qǐng)求都是可以發(fā)送出去的,但是在 web 端,瀏覽器里,這么做的就不合適,如果網(wǎng)絡(luò)上的接口可以不受限制的被任意人調(diào)用,那將是一個(gè)非?;靵y的場(chǎng)景,所以,為了防止這種情況,瀏覽器做了這個(gè)同源策略來(lái)防止這種情況發(fā)生。

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

總結(jié):協(xié)議相同+域名相同+端口號(hào)相同,瀏覽器才認(rèn)為是同一個(gè)網(wǎng)站,才不會(huì)受到同源策略的影響,才可以正常的發(fā)送Ajax請(qǐng)求。

所謂的同源策略是瀏覽器實(shí)現(xiàn)的,而和后臺(tái)服務(wù)器無(wú)關(guān),A 發(fā)送請(qǐng)求到 B. 請(qǐng)求實(shí)際上是發(fā)送到了 B 后臺(tái), B后臺(tái)接受到數(shù)據(jù)后。

其實(shí)也有返回,只不過(guò),這個(gè)數(shù)據(jù)返回到瀏覽器之后,瀏覽器把這個(gè)數(shù)據(jù)給劫持了,不讓A網(wǎng)站使用

既然跨域這么麻煩,為什么要進(jìn)行跨域?

因?yàn)楫?dāng)一個(gè)項(xiàng)目變大時(shí),把所有的內(nèi)容都丟在一個(gè)網(wǎng)站或者是后臺(tái)服務(wù)器中是不現(xiàn)實(shí)的.

2. 跨域資源共享(CORS)

CORS是一種標(biāo)準(zhǔn)機(jī)制,允許Web應(yīng)用程序在跨域訪問(wèn)資源時(shí),通過(guò)設(shè)置特定的HTTP響應(yīng)頭來(lái)放寬瀏覽器的同源策略限制。

3. 預(yù)檢請(qǐng)求(Preflight Request)

預(yù)檢請(qǐng)求是CORS機(jī)制中的一部分,它是瀏覽器為了安全考慮而自動(dòng)發(fā)起的一種請(qǐng)求,主要用于復(fù)雜的跨域請(qǐng)求前的“探路”。這種請(qǐng)求使用HTTP的OPTIONS方法,目的是為了確認(rèn)服務(wù)器是否允許特定的跨域請(qǐng)求。

三、Gin框架中解決跨域問(wèn)題的方法

方法一:自定義中間件

在Gin框架中,可以通過(guò)自定義中間件的方式來(lái)解決跨域問(wèn)題。以下是一個(gè)自定義中間件的示例代碼:

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"
)

// 跨域中間件
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method // 請(qǐng)求方法
		origin := c.Request.Header.Get("Origin") // 請(qǐng)求頭部
		var headerKeys []string // 聲明請(qǐng)求頭keys
		for k, _ := range c.Request.Header {
			headerKeys = append(headerKeys, k)
		}
		headerStr := strings.Join(headerKeys, ", ")
		if headerStr != "" {
			headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
		} else {
			headerStr = "access-control-allow-origin, access-control-allow-headers"
		}
		if origin != "" {
			c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
			c.Header("Access-Control-Allow-Origin", "*") // 允許訪問(wèn)所有域
			c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE") // 服務(wù)器支持的所有跨域請(qǐng)求的方法
			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") // 允許的頭類(lèi)型
			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") // 允許跨域設(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!")
		}
		// 處理請(qǐng)求
		c.Next()
	}
}

func main() {
	engine := gin.Default()
	// 允許使用跨域請(qǐng)求,全局中間件
	engine.Use(Cors())
	engine.Run(":11000") // 運(yùn)行啟動(dòng)端口
}

在上述代碼中,定義了一個(gè)名為Cors的中間件函數(shù),該函數(shù)通過(guò)設(shè)置HTTP響應(yīng)頭來(lái)允許跨域請(qǐng)求。在main函數(shù)中,通過(guò)engine.Use(Cors())將中間件應(yīng)用到全局路由上。

方法二:使用第三方庫(kù)github.com/gin-contrib/cors

Gin框架自身并未內(nèi)置CORS支持,但有一個(gè)官方推薦的、與Gin高度集成的第三方庫(kù)github.com/gin-contrib/cors可以方便地解決這個(gè)問(wèn)題。以下是使用第三方庫(kù)解決跨域問(wèn)題的步驟:

添加依賴

在你的項(xiàng)目中添加github.com/gin-contrib/cors依賴:

go get -u github.com/gin-contrib/cors

創(chuàng)建CORS配置

創(chuàng)建一個(gè)cors.Config結(jié)構(gòu)體實(shí)例,用于定義你的CORS策略。以下是一些常見(jiàn)的配置選項(xiàng):

package conf

import (
    "github.com/gin-contrib/cors"
    "time"
)

var CorsConfig = cors.Config{
    AllowAllOrigins:  false,
    AllowOrigins:     []string{"http://localhost:3000"}, // 允許的源,生產(chǎn)環(huán)境中應(yīng)替換為具體的允許域名
    AllowOriginFunc:  func(origin string) bool { return true }, // 自定義函數(shù)來(lái)判斷源是否允許
    AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"}, // 允許的HTTP方法列表
    AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization"}, // 允許的HTTP頭部列表
    AllowCredentials: true,                             // 是否允許瀏覽器發(fā)送Cookie
    MaxAge:           10 * time.Minute,                 // 預(yù)檢請(qǐng)求(OPTIONS)的緩存時(shí)間(秒)
}

使用CORS中間件

在Gin的路由器上應(yīng)用CORS中間件:

package main

import (
    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
    "goproject/conf" // 引入CORS配置
)

func main() {
    router := gin.Default()
    // 使用配置好的CORS規(guī)則
    router.Use(cors.New(conf.CorsConfig))

    // 定義路由
    router.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })

    router.Run(":8080") // 啟動(dòng)服務(wù)器
}

在上述代碼中,首先定義了CORS配置CorsConfig,然后在Gin路由器上通過(guò)router.Use(cors.New(conf.CorsConfig))應(yīng)用了CORS中間件。這樣,所有經(jīng)過(guò)這個(gè)路由器的請(qǐng)求都會(huì)先經(jīng)過(guò)CORS中間件的處理,自動(dòng)添加相應(yīng)的CORS響應(yīng)頭。

方法三:JSONP請(qǐng)求(不推薦)

JSONP是一種較老的技術(shù),用于解決跨域問(wèn)題。然而,由于其安全性和靈活性不如CORS,現(xiàn)代瀏覽器已逐漸棄用JSONP。因此,在可能的情況下,建議優(yōu)先考慮實(shí)現(xiàn)CORS。然而,如果你需要支持舊版客戶端或CORS不可行的特定場(chǎng)景,JSONP仍可作為一種可行的解決方案。

以下是一個(gè)使用JSONP的示例代碼:

package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()

	// JSONP請(qǐng)求處理
	router.GET("/jsonp", func(c *gin.Context) {
		callback := c.Query("callback")
		data := map[string]interface{}{
			"title": "標(biāo)題-jsonp",
			"desc":  "說(shuō)明-jsonp",
			"content": "內(nèi)容-jsonp",
		}
		c.JSONP(200, data)
	})

	router.Run(":8080")
}

在上述代碼中,定義了一個(gè)/jsonp路由,該路由通過(guò)c.JSONP(200, data)方法返回JSONP響應(yīng)??蛻舳丝梢酝ㄟ^(guò)添加callback參數(shù)來(lái)接收J(rèn)SONP響應(yīng)。

四、總結(jié)

跨域問(wèn)題是Web開(kāi)發(fā)中的一個(gè)常見(jiàn)問(wèn)題,特別是在前后端分離的項(xiàng)目中。在Gin框架中,處理跨域問(wèn)題可以通過(guò)自定義中間件、使用第三方庫(kù)或JSONP等方式來(lái)實(shí)現(xiàn)。其中,使用自定義中間件和第三方庫(kù)是兩種常見(jiàn)且有效的方法。通過(guò)合理配置CORS策略,可以確保Web應(yīng)用程序能夠正確處理跨域請(qǐng)求,同時(shí)保障用戶數(shù)據(jù)的安全。

在實(shí)際應(yīng)用中,開(kāi)發(fā)者應(yīng)根據(jù)具體的安全需求和交互模式來(lái)配置CORS策略。例如,可以限制允許跨域請(qǐng)求的域名、方法、頭部等,以確保只有符合條件的請(qǐng)求能夠被處理。此外,還需要注意處理預(yù)檢請(qǐng)求,以確保復(fù)雜的跨域請(qǐng)求能夠成功通過(guò)。

以上就是在Gin框架中解決跨域問(wèn)題的多種方法的詳細(xì)內(nèi)容,更多關(guān)于Gin框架跨域問(wèn)題的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go?Error?嵌套實(shí)現(xiàn)創(chuàng)建方式

    Go?Error?嵌套實(shí)現(xiàn)創(chuàng)建方式

    這篇文章主要介紹了Go?Error?嵌套到底是怎么實(shí)現(xiàn)的?大家都知道創(chuàng)建error有兩種方式分別是errors.new()另一種是fmt.errorf(),本文通過(guò)詳細(xì)例子給大家介紹,需要的朋友可以參考下
    2022-01-01
  • Go Web框架gin的入門(mén)教程

    Go Web框架gin的入門(mén)教程

    本篇文章主要介紹了Go Web框架gin的入門(mén)教程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • golang標(biāo)準(zhǔn)庫(kù)time時(shí)間包的使用

    golang標(biāo)準(zhǔn)庫(kù)time時(shí)間包的使用

    時(shí)間和日期是我們編程中經(jīng)常會(huì)用到的,本文主要介紹了golang標(biāo)準(zhǔn)庫(kù)time時(shí)間包的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 淺析Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作

    淺析Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作

    這篇文章主要為大家詳細(xì)介紹了Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Go語(yǔ)言有一定的幫助,需要的可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • 關(guān)于Go 是傳值還是傳引用?

    關(guān)于Go 是傳值還是傳引用?

    這篇文章主要討論Go語(yǔ)言 是傳值還是傳引用?文章先從Go 官方的定義展開(kāi),隨后是傳值和傳引用得介紹到map 和 slice得區(qū)別,需要的小伙伴可以參考一下文章得具體內(nèi)容
    2021-10-10
  • Go語(yǔ)言中工作池的原理與實(shí)現(xiàn)

    Go語(yǔ)言中工作池的原理與實(shí)現(xiàn)

    工作池是一種并發(fā)編程模式,它使用一組固定數(shù)量的工作線程來(lái)執(zhí)行任務(wù)隊(duì)列中的工作單元,本文將介紹工作池的工作原理,并通過(guò)代碼示例演示其在實(shí)際應(yīng)用中的用途,有需要的可以參考下
    2023-10-10
  • Golang CSP并發(fā)機(jī)制及使用模型

    Golang CSP并發(fā)機(jī)制及使用模型

    這篇文章主要為大家介紹了Golang CSP并發(fā)機(jī)制及使用模型,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Go+Redis實(shí)現(xiàn)常見(jiàn)限流算法的示例代碼

    Go+Redis實(shí)現(xiàn)常見(jiàn)限流算法的示例代碼

    限流是項(xiàng)目中經(jīng)常需要使用到的一種工具,一般用于限制用戶的請(qǐng)求的頻率,也可以避免瞬間流量過(guò)大導(dǎo)致系統(tǒng)崩潰,或者穩(wěn)定消息處理速率。這篇文章主要是使用Go+Redis實(shí)現(xiàn)常見(jiàn)的限流算法,需要的可以參考一下
    2023-04-04
  • 一文了解Go語(yǔ)言中編碼規(guī)范的使用

    一文了解Go語(yǔ)言中編碼規(guī)范的使用

    這篇文章主要介紹了一文了解Go語(yǔ)言中編碼規(guī)范的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Go語(yǔ)言中Slice常見(jiàn)陷阱與避免方法詳解

    Go語(yǔ)言中Slice常見(jiàn)陷阱與避免方法詳解

    這篇文章主要為大家詳細(xì)介紹的是 Go 語(yǔ)言中的 Slice 的常見(jiàn)陷阱以及如何避免這些錯(cuò)誤,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2023-02-02

最新評(píng)論