Angular 前端 POST 到 Golang 后端方法不允许并被 CORS 策略阻止

我正在尝试从我的 Angular 前端向我的 Golang 后端发出发布请求,两者都由同一台机器提供。我不断得到:

OPTIONS http://localhost:12345/anteroom 405 (Method Not Allowed)

Access to XMLHttpRequest at 'http://localhost:12345/anteroom' from origin 'http://localhost:4200' 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.

Golang 后端,使用 Gorilla mux 路由器:

func main() {

    router := mux.NewRouter()

    router.HandleFunc("/anteroom", anteroom).Methods("POST")

    log.Fatal(http.ListenAndServe(":12345", router))

}


func anteroom(res http.ResponseWriter, req *http.Request) {

    res.Header().Set("Access-Control-Allow-Origin", "*")

    // *Edit 17 Jan 19 12.44pm*: Billy, user268396, and Peter suggest that OPTIONS should be added. As mentioned below, I've already tried that.

    res.Header().Set("Access-Control-Allow-Methods", "POST")

    res.Header().Set("Content-Type", "application/json")


    // Put it into a struct variable and print a bit of it.

    _ = json.NewDecoder(req.Body).Decode(&member)

    fmt.Println(member.ID)

}


慕田峪9158850
浏览 119回答 3
3回答

倚天杖

这不是你CORS在后端的做法。您的后端需要侦听 HTTPOPTIONS类型的请求并将 CORS 标头发送到那里。控制流程大致是:你在前端请求一些东西浏览器判断:呃哦,这需要 CORS浏览器首先对请求的资源进行OPTIONS请求,协商CORS根据结果,任一浏览器都会向您的前端抛出错误或者它继续您的前端发出的实际请求。从现在开始一切正常当浏览器获得您的实际 API 回调的结果时,它会过滤掉未在步骤 3 和 4 中列入白名单/协商的内容。作为 HTTP 调用的结果,它将可能被审查的结果呈现给前端。

潇潇雨雨

问题的解决在很大程度上要感谢所有帮助我意识到我没有正确执行 CORS 的人。基本上,有两个问题:1. 我不知道在后端正确设置标头,以及 2. 我没有正确格式化我的 JSON 数据。通常,它很简单:当你想要请求某些东西时,浏览器会根据你已有的内容设置适当的标头,然后将请求发送出去。服务器响应。但是,假设您在同一域的后端和前端有一个 API POST 端点(我想我们大多数人都在开发,但可能不在生产中),并且您正在使用 application/x 以外的任何东西-www-form-urlencoded,multipart/form-data,还有text/plain,那就有点不一样了。就我而言,我正在使用 application/json。所以,它看起来像这样:浏览器使用 OPTIONS 方法发送请求,询问允许使用哪些方法和内容类型以及其他内容。这称为预检请求。它还没有发送我的 JSON 对象。服务器响应预检请求。为了让服务器响应允许的内容,我们需要正确设置后端以允许 Access-Control-Allow-Methods 中的 OPTIONS 方法,如果您像我一样使用 Gorilla mux,请记住也允许它进入router.HandleFunc()。因为我们的前后端在同一个域(http://localhost),最简单的做法是将 Access-Control-Allow-Origin 设置为“*”。但是,根据我们的需要,我们可能不想在生产中这样做,因为 * 意味着全世界及其他地方都可以发送请求。因为我要接收JSON,所以我在后端也设置了Content-Type为application/json。这是我问题的另一半。长话短说,无论对其他人有用的是什么,出于某种原因我仍然必须应用JSON.stringify()到我的原始 JSON 数据。然后它完美地工作。一旦浏览器收到允许的 OPTIONS,它就会过滤掉不允许的内容,并发回仅包含适当数据的请求。在我的例子中,这将是 JSON 对象。就是这样。

慕田峪7331174

“ Access-Control-Allow-Origin”表示您允许向该服务器发出请求的来源。它可以是以下形式:“*”“ https://github.com ”“ http://127.0.0.1:8080 ”“铬扩展:// *”“*.some-domain.com”Access-Control-Allow-Methods当你想从 CORS 发布数据时,“ ” 应该是 []string("POST", "OPTION") 。说到golang,看godoc https://golang.org/pkg/net/http/#Headertype Header map[string][]string而且我总是建议使用Header.Add()instead ofHeader.Set()除非你确切地知道你在做什么。因为 header 中的每个值总是 []string。所以应该是  res.Header().Add("Access-Control-Allow-Origin", "*")     res.Header().Add("Access-Control-Allow-Methods", "POST")     res.Header().Add("Access-Control-Allow-Methods", "OPTION")     res.Header().Add("Content-Type", "application/json")
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go