跨域请求

前端跨域请求,后端需要支持,使用go+gin进行跨域处理。很方便

package middleware

import (
	"dzpost-server/app/config"
	"github.com/gin-gonic/gin"
	"net/http"
)

func CORS(cfg *config.Config) gin.HandlerFunc {

	return func(ctx *gin.Context) {
		var (
			origin string
			result string
		)

		result = "https://"
		if ctx.Request.TLS == nil {
			result = "http://"
		}
		result += ctx.Request.Host
		origin = ctx.Request.Header.Get("Origin")

		if origin != "" {
			var exists bool
			for _, v := range cfg.CORS.Allows {
				if v == origin || v == "*" {
					exists = true
					break
				}
			}
			if !exists {
				ctx.AbortWithStatus(http.StatusForbidden)
				return
			}
			result = origin
		}

		if ctx.Request.Method == "OPTIONS" {
			result = "*"
		}

		if result != "" {
			ctx.Header("Access-Control-Allow-Origin", result)
			ctx.Header("Access-Control-Allow-Credentials", "true")
			ctx.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With, X-Client-Info")
			ctx.Header("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
		}

		if ctx.Request.Method == "OPTIONS" {
			ctx.AbortWithStatus(http.StatusNoContent)
			return
		}

		ctx.Next()

		return
	}
}

注意

前端发送的header中的Origin 是可以伪造的,只是浏览器会自动带上。但可以伪造。
vue.js 中如果有跨域,如果不是GET请求,axios 会先发送 OPTIONS 请求。