Axios中每次发送post请求前都会发送options请求

今天写前端的时候,发现每次post请求都会失败, 反复调试过后发现axios在每次发送post请求前都发送了options请求, 在网络搜罗了一大圈, 发现了原因是因为web页面发送了请求给vue后, vue再请求后端过程中发生了跨域, 而我使用的不是默认的跨域允许请求头, 而是content-type: application/json, 所以浏览器认为跨域即是不可靠行为, 所以每次都需要发送options请求, 进行跨域检测, 所以导致了每次options请求失败了, 所以post请求就没有下文了。

问题来了, 之前我也用vue+axios写了前端, 为什么不会出现这样的情况呢?

首先我以为是配置的问题, 把axios拦截器里面的content-type改成了application/x-www-form-urlencoded, 结果发现确实不会再options的, 但是之前用的时候, 也跨域了, 但是却没有出现options。

然后我以为是axios的版本问题, 就把axios从1.6.5降到了之前写的时候的1.6.2, 结果发现问题依旧,说明问题和版本无关。

然后就想到了, 问题是基于跨域引起的, 那是不是因为后端没有设置跨域呢? 但是之前用Django写的后台也没有带跨域设置, Goframe应该也不用才对?

抱着试一试的态度, 搜索了下GoFrame怎么设置跨域, 其实很简单, GoFrame已经帮我们做了封装, 在中间件中加入一个允许跨域的方法就行了。

Go 复制代码
func MiddlewareHandlerResponse(r *ghttp.Request) {
	r.Response.CORSDefault()
	r.Middleware.Next()
}

然后在你的cmd中加入中间件即可

Go 复制代码
var (
	Main = gcmd.Command{
		Name:  "main",
		Usage: "main",
		Brief: "start http server",
		Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
			s := g.Server()
			s.Use(MiddlewareHandlerResponse)

			s.Group("/api", func(group *ghttp.RouterGroup) {
				group.Group("/v1", func(group *ghttp.RouterGroup) {
					group.Bind(hb.NewV1())
				})
			})
			s.Run()
			return nil
		},
	}
)

然后再次进行尝试, 问题解决了。

仔细对照了一下, 后端加入了跨域后, 响应头多了如下几个请求头

也就是多了一些允许跨域的设置, 这也是GoFrame帮忙封装的, 并且在源码中, 我们可以看到它针对OPTIONS请求都做了处理的。

Go 复制代码
func (r *Response) CORS(options CORSOptions) {
	if r.CORSAllowedOrigin(options) {
		r.Header().Set("Access-Control-Allow-Origin", options.AllowOrigin)
	}
	if options.AllowCredentials != "" {
		r.Header().Set("Access-Control-Allow-Credentials", options.AllowCredentials)
	}
	if options.ExposeHeaders != "" {
		r.Header().Set("Access-Control-Expose-Headers", options.ExposeHeaders)
	}
	if options.MaxAge != 0 {
		r.Header().Set("Access-Control-Max-Age", gconv.String(options.MaxAge))
	}
	if options.AllowMethods != "" {
		r.Header().Set("Access-Control-Allow-Methods", options.AllowMethods)
	}
	if options.AllowHeaders != "" {
		r.Header().Set("Access-Control-Allow-Headers", options.AllowHeaders)
	}
	// No continue service handling if it's OPTIONS request.
	// Note that there's special checks in previous router searching,
	// so if it goes to here it means there's already serving handler exist.
	if gstr.Equal(r.Request.Method, "OPTIONS") {
		if r.Status == 0 {
			r.Status = http.StatusOK
		}
		// No continue serving.
		r.Request.ExitAll()
	}
}
相关推荐
女王大人万岁10 小时前
Go标准库 io与os库详解
服务器·开发语言·后端·golang
女王大人万岁12 小时前
Go语言time库核心用法与实战避坑
服务器·开发语言·后端·golang
Tony Bai13 小时前
【分布式系统】11 理论的试金石:用 Go 从零实现一个迷你 Raft 共识
开发语言·后端·golang
浮尘笔记14 小时前
Go语言并发安全字典:sync.Map的使用与实现
开发语言·后端·golang
小二·15 小时前
Go 语言系统编程与云原生开发实战(第3篇):企业级 RESTful API 开发 —— 中间件、验证、文档与权限控制
云原生·golang·restful
还在忙碌的吴小二16 小时前
Go-View 数据可视化大屏使用手册
开发语言·后端·信息可视化·golang
小二·18 小时前
Go 语言系统编程与云原生开发实战(第4篇):数据持久化深度实战 —— PostgreSQL、GORM 与 Repository 模式
postgresql·云原生·golang
学海无涯,行者无疆19 小时前
前端 Axios 深度封装实战:拦截器 + 文件处理 + 业务接口统一管理
axios·前后端交互·axios使用·axios实战·axios封装·axios详解·axios用法
女王大人万岁19 小时前
Go标准库 path 详解
服务器·开发语言·后端·golang
LuminescenceJ19 小时前
RPC通信中的Context上下文如何跨进程传递消息,gRPC为例分析
开发语言·网络·后端·网络协议·rpc·golang