什么是跨域?
瀏覽器有一個安全機制叫同源策略。
同源就是指協(xié)議、域名、端口都一樣,如果任意一項不一致就是不同源。簡單點說就是,你的網(wǎng)頁URL和你調(diào)用的接口URL不是一個地方的,瀏覽器覺得有安全風險,不想讓你使用這個接口的數(shù)據(jù)。
跨域的現(xiàn)象
當我們在本地啟動前、后端代碼進行調(diào)試時,如果使用postman等類似的工具進行調(diào)試時,接口是可以請求的,但是在瀏覽器調(diào)用相同的請求會失敗。
這是因為使用工具調(diào)用接口只是簡單的訪問一個資源,并不存在資源的相互訪問。而使用web則觸發(fā)了同源策略的保護機制。
gin處理跨域
我們在gin的攔截器中定義允許跨域請求,同時需要在注冊url的時候使用這個攔截器的方法
// 跨域
Router.Use(middleware.Cors()) // 如需跨域可以打開
// 處理跨域請求,支持options訪問
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
// 放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 處理請求
c.Next()
}
}
到這里就結(jié)束了嘛?
如果你的攔截器方法中定義了你前段請求攜帶的所有信息的話,那么請求就能成功。
但是我使用的newbee商城現(xiàn)成的前端,其前端代碼中攜帶了這樣一條請求頭的鍵值對
axIOS.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
如果不加上這個請求頭的話,通過web請求接口依然會失敗。
在你的項目中如果也遇到了類似的問題,可以檢查一下你前后端定義的請求頭是否一致。
所有代碼已上傳github,有興趣的可以訪問
https://github.com/newbee-ltd/newbee-mall-api-go/,如果有更好的建議也歡迎提交issure,pr