跨域问题

发布时间 2023-04-24 21:54:57作者: bhxuwei

可以在后端接口层或nginx代理层做配置,不过只需要一处做配置,重复的话会报错。

golang gin配置

// 处理跨域请求,支持options访问
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method

		// 允许跨域,同一顶级域名的cookie共享
		c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))

		// 允许request headers中自定义参数,如果request headers中自定义参数不在当中,会引发跨域错误
		c.Header("Access-Control-Allow-Headers", "Content-Type,contenttype,AccessToken,X-CSRF-Token,Authorization,Token,x-token,x-user-id")
		
		// 允许跨域的方法
		c.Header("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT,OPTIONS")

		// 后端在 response headers 中自定义了参数,跨域允许前端拿到
		c.Header("Access-Control-Expose-Headers", "Content-Length,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Content-Type,token")
		
		// 允许携带根域名下的cookies
		c.Header("Access-Control-Allow-Credentials", "true")
		
		// 用来指定本次预检请求的有效期,单位为秒,,在此期间不用发出另一条预检请求
		c.Header("Access-Control-Max-Age", "3600")

		//放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}
		// 处理请求
		c.Next()
	}
}

func Routers() *gin.Engine {
	Router := gin.Default()
	Router.Use(Cors())
}

nginx代理配置

如果后端api接口项目没配置,也可以在nginx层做配置

# 未来产业
server {
        listen 443 ssl http2;
        server_name xxx.com;  # 自己的域名,请求头中不同host分发到对应虚拟主机
        add_header Strict-Transport-Security "max-age=31536000" always;

        ssl_certificate /etc/nginx/conf.d/gkx_ssl/ssl.crt;
        ssl_certificate_key /etc/nginx/conf.d/gkx_ssl/ssl.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;

        client_max_body_size 1024m;

        location / {
            # 允许跨域;后端设置了,nginx就不用设置了,不然会重复报错
            add_header Access-Control-Allow-Origin $http_origin;
            add_header Access-Control-Allow-Credentials true;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

            if ($request_method = 'OPTIONS') {
                return 204;
            }

            proxy_pass   http://127.168.0.3:808/;
            proxy_http_version  1.1;
            proxy_set_header    Connection "";
            proxy_set_header Host $host;
            proxy_connect_timeout 5;

            #下边是为获取真实IP所做的设置
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header    HTTP_X_FORWARDED_FOR $remote_addr;
            proxy_set_header    X-Forwarded-Proto $scheme;
            proxy_redirect      default;
        }
    }

server {
        listen 80; # 监听80端口
        server_name xxx.com;  # 绑定证书的域名

        # 强制将http的URL重写成https
        return 301 https://xxx.com$request_uri;

    }