浏览器有一个安全机制叫同源策略。
同源就是指协议、域名、端口都一样,如果任意一项不一致就是不同源。简单点说就是,你的网页URL和你调用的接口URL不是一个地方的,浏览器觉得有安全风险,不想让你使用这个接口的数据。
当我们在本地启动前、后端代码进行调试时,如果使用postman等类似的工具进行调试时,接口是可以请求的,但是在浏览器调用相同的请求会失败。
这是因为使用工具调用接口只是简单的访问一个资源,并不存在资源的相互访问。而使用web则触发了同源策略的保护机制。
我们在gin的拦截器中定义允许跨域请求,同时需要在注册url的时候使用这个拦截器的方法
// 跨域
Router.Use(middleware.Cors()) // 如需跨域可以打开
// 处理跨域请求,支持options访问
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,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")
// 放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 处理请求
c.Next()
}
}
到这里就结束了嘛?
如果你的拦截器方法中定义了你前段请求携带的所有信息的话,那么请求就能成功。
但是我使用的newbee商城现成的前端,其前端代码中携带了这样一条请求头的键值对
axIOS.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
如果不加上这个请求头的话,通过web请求接口依然会失败。
在你的项目中如果也遇到了类似的问题,可以检查一下你前后端定义的请求头是否一致。
所有代码已上传Github,有兴趣的可以访问
https://github.com/newbee-ltd/newbee-mall-api-go/,如果有更好的建议也欢迎提交issure,pr