尽管为Nginx,angular-http-server和Golang启用了“ CORS请求未成功”

时间:2019-03-06 20:36:03

标签: angular go nginx cors

我已经在开发中成功启用了CORS。我的Golang后端与本地计算机上的Angular前端通信良好。但是,我不知道如何在生产中启用CORS(DigitalOcean上的Ubuntu)。我在Firefox上得到了这个

“跨域请求被阻止:同源策略禁止读取http://localhost:12345/anteroom处的远程资源。(原因:CORS请求未成功)。”

我正在使用systemd单元运行Golang后端,并在localhost:12345上提供它。

我正在将Angular前端作为使用PM​​2和angular-http-server的构建(使用--prod标志构建)运行,并从8080端口提供服务。该端口位于防火墙后面。我使用Nginx来处理此前端的HTTPS流量。它在端口80上侦听,并在端口8080上将(proxy_pass)请求传递给它。着陆页(仅需要GET请求)在浏览器中加载正常,因此此设置似乎可行。

我使用的版本:Ubuntu 16.04,PM2 3.3.1,Angular CLI 7.3.4,angular-http-server 1.8.1

当前端尝试将JSON数据发布到后端时,就会发生问题(如上面的消息所示,localhost:12345 / anteroom)。

我读到CORS是服务器端的问题。因此,我尝试在有服务器的任何地方(即后端Nginx和angular-http-server)启用它。

它已在我的Golang代码中启用:

func anteroom(res http.ResponseWriter, req *http.Request) {
    res.Header().Set("Access-Control-Allow-Origin", "*")
    res.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
    res.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    res.Header().Set("Content-Type", "application/json")
...
}

func main() {
    ...
    # Using Gorilla mux router.
    router := mux.NewRouter()
    router.HandleFunc("/anteroom", anteroom).Methods("POST", "OPTIONS")
}

这成功地启用了CORS的开发功能,在该服务中,为Golang提供服务只是打开其内置的二进制文件,而为Angular提供ng serve

以上内容在生产中还不够。因此,我尝试使用angular-http-server启用它。注意结尾处的--cors标志:

pm2 start $(which angular-http-server) --name app -- --path /PATH/TO/DIST -p 8080 --cors

我还尝试过在与Angular前端构建有关的Nginx文件中启用它(改编自here):

location / {
if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type';
        add_header 'Content-Type' 'application/json';
        return 204;
     }

     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type';
        add_header 'Content-Type' 'application/json';
     }

     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type';
     }
proxy_pass http://localhost:8080;
}
}

我看过PM2,angular-http-server,Nginx和许多其他内容的文档,但我不知道自己缺少什么。让我知道?谢谢。

2 个答案:

答案 0 :(得分:0)

    func anteroom(res http.ResponseWriter, req *http.Request) {
    res.Header().Set("Access-Control-Allow-Origin", "*")
    res.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
    res.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    res.Header().Set("Content-Type", "application/json")
...
}

func main() {
    ...
    # Using Gorilla mux router.
    router := mux.NewRouter()
    router.HandleFunc("/anteroom", anteroom).Methods("POST", "OPTIONS")
}

代码中缺少GET方法。

将此行res.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")更改为res.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")

答案 1 :(得分:0)

感谢Ravinder Payal,我使用tcpdump来回查看标题。简而言之,在某个时候,它使我意识到我应该将前端设置为与“ localhost”进行通信。显然,这意味着任何使用前端的客户端浏览器都将在其自己的本地计算机上进行查找。

为解决此问题,我为有角前端设置了单独的application environments。这样一来,前端就可以在分阶段中与localhost进行通信,并在生产环境中与我的后端域进行通信。