为了账号安全,请及时绑定邮箱和手机立即绑定

CORS 预检神秘地因大猩猩/处理程序而失败

CORS 预检神秘地因大猩猩/处理程序而失败

Go
翻翻过去那场雪 2022-10-17 09:53:42
我正在通过 Heroku 为我的应用程序发布一个 Golang API。无法让我的 webapp(Flutter/Dart 堆栈)真正从我的 api 获得成功的响应。但是,我可以使用本地的 curl 命令获得成功的响应。我已经阅读了几篇关于更改 Go mux 服务器和添加正确标头的文章,但这对我不起作用。我什至看到在我的 curl 请求期间返回了这些标头。真的可以使用一些帮助,因为这会减慢我的速度。本质上这是我创建服务器的主要课程import (    "api/preventative_care"    "api/user"    "github.com/gorilla/handlers"    "github.com/gorilla/mux"    "log"    "net/http"    "os")func main() {    log.SetFlags(log.LstdFlags | log.Llongfile)    router := mux.NewRouter()    // Where ORIGIN_ALLOWED is like `scheme://dns[:port]`, or `*` (insecure)    headersOk := handlers.AllowedHeaders([]string{"*"})    methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})    originsOk := handlers.AllowedOrigins([]string{"*"})    router.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {        log.Println("Up and running!")    })    router.HandleFunc("/api/login", user.LoginHandler).Methods("GET")    router.HandleFunc("/api/recommendations", preventative_care.RecommendationHandler).Methods("GET")    var port = os.Getenv("PORT")    log.Printf("Starting application on port %s\n", port)    //log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), router))    log.Fatal(http.ListenAndServe(":" + os.Getenv("PORT"), handlers.CORS(originsOk, headersOk, methodsOk)(router)))}调用此 API 的 dart 代码如下所示:    Map<String, String> headers = {      "content-type": "application/json",      "username": username,      "password": password    };    final response = await http.get(Uri.parse(uri), headers: headers);我以为我应该看到Access-Control-Allow-Origin: *那里添加了 Header ,但还没有我仍然获得 200 成功。但是,当我尝试使用我的 Webapp 从使用 Google Chrome 的登录屏幕点击 API 时,我看到了这个错误:从源“https://my-app-staging.herokuapp.com”访问“https://my-app-api.herokuapp.com/api/login”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检的响应请求未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。不知道 - 好像标题正在被 Chrome 或其他东西删除?
查看完整描述

1 回答

?
www说

TA贡献1775条经验 获得超8个赞

gorilla/handlers不(还没有?)支持Access-Control-Allow-Headers. 您必须明确指定所有允许的标头。在你的情况下,而不是

handlers.AllowedHeaders([]string{"*"})

你应该有

handlers.AllowedHeaders([]string{"content-type", "username", "password"})

更多细节

早在 2016 年Fetch 标准Access-Control-Allow-Headers就增加了对标头中通配符的支持(在非凭据请求的情况下)。大多数现代浏览器现在都支持此功能

然而,gorilla/handlers似乎还没有赶上规范。如果您检查functionmethod的源代码handlers.AllowedHeaders*cors.ServeHTTP您会发现没有对"*"值进行特殊处理:它是按字面意思处理的。结果,CORS 中间件检测到您的预检请求(content-type、、usernamepassword)提供的请求标头与您允许的标头(*字面意思)之间的不匹配,并以 a 响应,403甚至没有设置Access-Control-Allow-Origin标头,从而导致访问控制检查失败。


查看完整回答
反对 回复 2022-10-17
  • 1 回答
  • 0 关注
  • 68 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信