问题描述
小编最近开发一款测试工具,前端用VUE写的,后端用golang,前后端都写好了以后,想本地启动联调一下,没想到,这一启动就启动了2天才起来,问题出在哪了呢?
Access to XMLHttpRequest at 'http://localhost:8080/demo?text=xiaoli' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
没错,跨域问题(下面贴的报错的url脱敏了),其实这个问题很常见,小编一点也不慌,因为小编知道加个配置就好了,就像下面一样
按照AI的解决方式,
前端需要在vue.config.js中加下配置
module.exports = {
devServer: {
proxy: {
'/demo': {
target: 'http://localhost:8080', // 目标服务器
changeOrigin: true, // 修改请求头中的 Origin 字段
secure: false, // 如果使用 https 时设置为 true
},
},
},
};
然后在服务端加个cors
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
// 设置允许跨域的头部
w.Header().Set("Access-Control-Allow-Origin", "*") // 允许所有来源
w.Header().Set("Access-Control-Allow-Methods", "GET, POST") // 允许的请求方法
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") // 允许的请求头
// 处理预检请求
if r.Method == http.MethodOptions {
return
}
// 发送响应数据
fmt.Fprintf(w, "Hello, CORS-enabled world!")
}
func main() {
http.HandleFunc("/demo", handler)
http.ListenAndServe(":8080", nil)
}
以上部分是ai给的解决方案
然后,小编一顿操作猛如虎,启动之后居然还是报错,反反复复检查了好几次,配置没问题啊
解决方式
最后在小编反复debug了一天之后终于发现了问题,小编在golang服务配置cors代码时,加在了这里
baseGroup := router.Group("/go-components/api/demo")
// 最刚开始加在这里了,当时想的是只对这个路由生效
baseGroup.Use(middleware.Cors())
baseGroup.POST("/getStoreInfo", webx.NewController(appKeyController.GetStoreInfo))
后来小编把这段代码加在了前面
router.Use(middleware.Cors())
baseGroup := router.Group("/go-components/api/demo")
然后重新启动就好了,太神奇了
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
if origin != "" {
c.Writer.Header().Add("Access-Control-Allow-Origin", origin)
// 仅POST, GET, OPTIONS请求支持跨域
c.Writer.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
c.Writer.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, uid")
c.Writer.Header().Add("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
c.Writer.Header().Add("Access-Control-Allow-Credentials", "true")
}
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
c.Next()
}
}
注意2个点:
1、c.Writer.Header().Add("Access-Control-Allow-Origin", origin)
,这个Access-Control-Allow-Origin的值不能设置成*,会报错的。
2、cors的几个配置都要加在c.Writer.Header().Add
里,而不是c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
,别问我是什么知道的!!!
就这些吧