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

I've enabled CORS successfully in development. My Golang back end communicates well with my Angular front end on my local machine. However, I can't figure out how to enable CORS in production (Ubuntu on DigitalOcean). I get this on Firefox:

"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:12345/anteroom. (Reason: CORS request did not succeed)."

I'm running the Golang back end with a systemd unit and serving it at localhost:12345.

I'm running the Angular front end as a build (built with --prod flag) using PM2 with angular-http-server, and serving it out of port 8080. This port is behind a firewall. I use Nginx to handle HTTPS traffic for this front end. It listens on port 80 and passes (proxy_pass) requests to it at port 8080. The landing page (which requires only a GET request) loads ok in the browser, so this setup seems feasible.

The versions I'm working with: Ubuntu 16.04, PM2 3.3.1, Angular CLI 7.3.4, angular-http-server 1.8.1.

The problem happens when the front end tries to POST JSON data to the back end (localhost:12345/anteroom, as seen in the message above).

I've read that CORS is a server-side issue. So, I've tried enabling it wherever I've a server, that is, in the back end, Nginx, and angular-http-server.

It's enabled in my Golang code:

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")
}

This successfully enables CORS in development, where serving Golang is just opening its built binary and Angular is served with ng serve.

The above isn't enough in production. So, I've tried enabling it with angular-http-server. Note the --cors flag at the end:

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

I've also tried enabling it in the Nginx file pertaining to the Angular front end build (adapted from 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;
}
}

I've looked at the documentation for PM2, angular-http-server, Nginx, and a bunch of other things and I don't know what I'm missing. Let me know? Thanks.

2个回答



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

为解决此问题,我设置了单独的应用环境用于我的前端。 这样一来,前端就可以在分阶段中与localhost进行通信,并在生产环境中与我的后端域进行通信。</ p>
</ div>

展开原文

原文

Thanks to Ravinder Payal, I used tcpdump to look at the headers going back and forth. To cut a very long story short, at some point it made me realise that I'd set the front end to communicate with "localhost". Obviously, that meant whichever client browser using the front end would be looking for it on its own local machine.

To solve this, I set up separate application environments for my angular front end. This allows the front end to communicate with localhost in staging and with my back end domain in production.



  func antroom(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(){
...
#使用大猩猩mux路由器。
router:= mux.NewRouter()
router.HandleFunc(“ / anteroom”,anteroom).Methods(“ POST”,“ OPTIONS” )
}
</ code> </ pre>

代码中缺少GET方法。</ p>

更改此行 res.Header( ).Set(“ Access-Control-Allow-Methods”,“ POST,OPTIONS”)</ code>到 res.Header()。Set(“ Access-Control-Allow-Methods”,“ GET,POST ,OPTIONS“)</ code> </ p>
</ div>

展开原文

原文

    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 method is missing in the code.

Change this line res.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") to res.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")

douzi8916
douzi8916 按照您的建议,我花了最后几天学习tcpdump来做到这一点,长话短说,这个错误是愚蠢的。 我将前端设置为与localhost通信。 显然,这意味着任何使用前端的客户端浏览器都将在其自己的本地计算机上进行查找。 所以谢谢。
一年多之前 回复
dsjws44266
dsjws44266 我的意思是*,但是,如果仍然无法正常工作,则还有其他问题。 在网络监视器中检查是否已显示设置的标题。
一年多之前 回复
doudao1282
doudao1282 您的意思是将通配符设置为“ *”,还是将其保留为“”? 我在Golang代码和Nginx中都尝试了通配符,但问题仍然存在。
一年多之前 回复
duanji9264
duanji9264 我可能还会使用其他方法发出其他请求,请尝试使用通配符()res.Header()。Set(“ Access-Control-Allow-Methods”,“”)
一年多之前 回复
doulei6330
doulei6330 谢谢,但是也没有用。
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问