gozero解决跨域
在做前后端分离的时候,我们通常会遇到跨域问题,之前我的解决办法是自定义跨域返回
1编写跨域中间件
package middleware
import "net/http"
// CorsMiddleware 跨域请求处理中间件
type CorsMiddleware struct {
}
// NewCorsMiddleware 新建跨域请求处理中间件
func NewCorsMiddleware() *CorsMiddleware {
return &CorsMiddleware{}
}
// Handle 跨域请求处理
func (m *CorsMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
setHeader(w)
// 放行所有 OPTIONS 方法
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
return
}
// 处理请求
next(w, r)
}
}
// Handler 跨域请求处理器
func (m *CorsMiddleware) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
setHeader(w)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
} else {
w.WriteHeader(http.StatusNotFound)
}
})
}
// setHeader 设置响应头
func setHeader(w http.ResponseWriter) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
w.Header().Set("Access-Control-Allow-Credentials", "true")
}
2 然后在入口文件中使用中间件
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf, rest.WithNotAllowedHandler(middleware.NewCorsMiddleware().Handler()))
defer server.Stop()
server.Use(middleware.NewCorsMiddleware().Handle)
ctx := svc.NewServiceContext(c)
handler.RegisterHandlers(server, ctx)
但是在使用到jwt的时候,遇到了一个问题,就是axios做请求的时候,如果token失效,那么axios将捕获不到后端返回的401代码,分析到的原因是token失效gozero会经过jwt认证中间件,直接返回401错误,并没有经过我们自定义的跨域中间件,直接导致请求是跨域的。
那我们就必须做出更改,所有响应返回都会经过我们自定的跨域中间件
修改如下:
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(nil, func (w http.ResponseWriter) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
w.Header().Set("Access-Control-Allow-Credentials", "true")
}, "*"))
defer server.Stop()
//server.Use(middleware.NewCorsMiddleware().Handle)
ctx := svc.NewServiceContext(c)
handler.RegisterHandlers(server, ctx)
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
server.Start()
}