# 老大难的跨域问题
我们在做前后端分离
的项目,时常会听到跨域问题。经常看到有人的文章标题写着: 前端支持跨域
,但显然也只是个噱头而已。
跨域的概念,本人才疏学浅,就不多说了。大家有兴趣可以搜搜相关的介绍。
# 为什么来卷go
由于Mdnice官方仓库已经很久没有维护了,个人的文章又多如牛毛
,在没有目录和搜索功能,官方忽略文件夹相关issue的情况下,我决定自己做一个超级低配版的mdnice
,虽然我厚颜无耻地叫它mdnice-plus。
加之也觉得自己2年左右没复习go了,需要再练练go,所以后端打算用gin+gorm来完成了。
今天就聊一聊在go的web框架gin里面怎么解决跨域问题,以及在实践过程中踩的坑
。
大概已经抄了mdnice一小部分功能了,差个图床和目录就差不多好了。它大概长这样:
# 解决方案(如果不生效请直接看踩坑指南)
民间版本 ⭐⭐⭐⭐
民间版本指的是非官方的版本,其实解决跨域无非是需要设置response header中的allow相关数据,所以在官方没有支持的情况下出了个民间版。
来看看大概版的:
// 文章转自知乎: https://zhuanlan.zhihu.com/p/228881482
package middleware
import (
"github.com/gin-gonic/gin"
"net/http"
)
func Cors() gin.HandlerFunc {
return func(context *gin.Context) {
method := context.Request.Method
context.Header("Access-Control-Allow-Origin", "*")
context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
context.Header("Access-Control-Allow-Credentials", "true")
if method == "OPTIONS" {
context.AbortWithStatus(http.StatusNoContent)
}
context.Next()
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
用法很简单,使用app.Use(Cors())
。
官方版本 ⭐⭐⭐⭐⭐
官方封装了一个gin-contrib/cors包,里面提供了cors.Config,可以让大家配置相关的跨域选项,简单用法如下:
import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
func main() {
app := gin.New()
app.Use(cors.Default())
}
2
3
4
5
6
7
8
9
10
比民间版本更推荐的原因,是代码量特别少,看起来和app.Use(log)这样的代码很接近。
# 踩坑指南
由于之前用的是iris这个web框架,所以对gin不是太了解。
如果app.Use(middleware)放在路由注册
之后,那么这个接口将不为跨域接口,也就是说app.Use跨域的时候,也是有讲究的。
这点很多文章都没有说(可能大家都明白这个?)所以有时候我配置了发现跨域没生效。
比如我这样写代码:
这样就会报错了,因为cors是最后才添加的。
但也有好处,如果我把需要登录的接口都放到app.Use(auth)之后,写接口的时候就方便许多,不需要额外处理了。
由于博主的go水平一般般,虚心接受大家提出的建议/意见~大家也要来卷go的话遇到跨域问题,可以来参考参考这篇文章=3=