gin框架中全局跨域请求处理设置

浏览器发送options预检请求的前提:

在非简单请求且跨域的情况下,浏览器会发起options预检请求

简单请求

需要满足以下两个条件
1. 请求方法
    get
    head
    post
2. http的头信息不超过以下几种字段
    Accept
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type:(只限于application/x-www-form-urlencoded、multipart/form-data、text/plain)

复杂请求

非简单请求即复杂请求,常见的复杂请求有
1. 请求方法为put或delete
2. Content-Type字段类型为:application/json
3. 添加额外的http header 比如:access_token
在跨域的情况下,非简单请求会先发起一次空body的OPTIONS预检请求
用于向服务器请求权限信息,等预检请求被成功响应后,才发起真正的http请求

浏览器的预检请求可以通过设置:Access-Control-Max-Age进行缓存

跨域访问的问题

OPTIONS请求

全局跨域访问中间件

// 跨域访问:cross origin resource share
func Cors() gin.HandlerFunc {
	return func(context *gin.Context) {
		method := context.Request.Method
		origin := context.Request.Header.Get("Origin")
		var headerKeys []string
		for k, _ := range context.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 = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers")
		}
		if origin != "" {
			context.Writer.Header().Set("Access-Control-Allow-Origin", "*")
			context.Header("Access-Control-Allow-Origin", "http://127.0.0.1:8080") // 设置允许访问所有域: *
			context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
			context.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")
			context.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")
			context.Header("Access-Control-Max-Age", "172800")
			context.Header("Access-Control-Allow-Credentials", "false")
			context.Set("content-type", "application/json") //// 设置返回格式是json
		}
		if method == "OPTIONS" {
			context.JSON(http.StatusOK, "Options Request!")
		}

		// 处理请求
		context.Next()
	}
}

跨域解决办法2

func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method

		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token, x-token")
		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, 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")

		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}
	}
}

跨域前端测试代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
    <button type="button" id="query">请求数据</button>
    <div id="content" style="background-color: aqua; width: 300px; height: 500px;"></div>
</body>
<script type="text/javascript">
    $("#query").click(function () {
        $.ajax(
            {
                url: "http://127.0.0.1:8021/u/v1/user/list",
                dataType: "json",
                type: "get",
                beforeSend: function (request) {
                    request.setRequestHeader("x-token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MjQsIk5pY2tOYW1lIjoi6ams6aao5b2kIiwiQXV0aG9yaXR5SWQiOjIsImV4cCI6MTY0ODUzODE5OSwiaXNzIjoic2Fua3VhbiIsIm5iZiI6MTY0NTk0NjE5OX0.0mkxmRhPgjDHSr48fbNn9I9FtPUGlop3807kAbJb74c")
                },
                success: function (result) {
                    console.log(result.data)
                    $("#content").text(result.data)
                },
                error: function (data) {
                    alert("请求出错")
                }
            }
        )
    })
</script>
</html>

posted @ 2021-12-11 12:25  专职  阅读(657)  评论(0编辑  收藏  举报