gpt4 book ai didi

angular - 405 Method Not Allowed and "CORS header ‘Access-Control-Allow-Origin’ missing“虽然tcpdump说它正在被发送出去

转载 作者:数据小太阳 更新时间:2023-10-29 03:20:15 24 4
gpt4 key购买 nike

这个问题遵循这个 one所以有些文字是一样的。

当前端尝试在提交表单时向后端发送 JSON 数据时,Firefox 控制台上的错误消息:

“跨源请求被阻止:同源策略不允许读取位于 https://backend_domain/anteroom 的远程资源。(原因:缺少 CORS header 'Access-Control-Allow-Origin')。”

我正在使用 systemd 单元运行 Golang 后端,并在 localhost:12345 提供服务。 Nginx 在端口 80 上监听并将请求向下传递给它:

listen 80;
server_name backend_domain;

location / {
include proxy_params;
proxy_pass http://localhost:12345/;
}

我正在运行 Angular 前端作为构建(使用 --prod 标志构建)使用 PM2 和 angular-http-server 在端口 8080 服务它。与后端相同,Nginx从端口 80 执行它的操作:

listen 80;
server_name frontend_domain;

location / {
include proxy_params;
proxy_pass http://localhost:8080/;
}

我正在使用的版本:Ubuntu 16.04、PM2 3.3.1、Angular CLI 7.3.4、angular-http-server 1.8.1。

开发者工具中 Firefox 的网络选项卡显示 POST 请求 header :

Host: backend_domain
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: frontend_domain/
Content-Type: text/plain
Content-Length: 111
Origin: frontend_domain
DNT: 1
Connection: keep-alive

响应头:

HTTP/1.1 405 Method Not Allowed
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 11 Mar 2019 21:08:24 GMT
Content-Length: 0
Connection: keep-alive
Strict-Transport-Security: max-age=31536000; includeSubDomains

当我点击提交按钮时应该去后端的实际请求是:

if (val.issues && val.age && val.gender) {
this.profile = JSON.stringify({
age: val.age,
gender: val.gender,
issues: val.issues
});

return this.http
.post(environment.anteroomPOSTURL, this.profile, {
observe: "response"
})

Firefox 显示此成功触发,JSON 显示在开发工具的“网络”中的“参数”选项卡下。

这个响应向我暗示,不知何故,Nginx 没有将请求向下传递到端口 12345 的后端。否则,它会从我的 Golang 代码中如下所示的后端检索 header 并将其传递回前端,对吧?

我读到 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

我也尝试在后端和前端 Nginx 文件中启用它(改编自 here ):

location / {
proxy_pass http://localhost:8080; # or 12345 if it's the back end conf
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';
}
}
}

奇怪的是,无论 header 是否在 Nginx 文件中,tcpdump -vvvs 1024 -l -A src host backend_domain | grep 'Access-Control-Allow-Origin:' 产生这个:

        Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *

不知道为什么它会重复 12 次,但无论如何,后端会在前端加载时发送上述内容(这意味着 Nginx 确实成功地将请求向下传递到端口 12345,对吧?)。当我单击提交按钮提交表单时,它不会发送它们。我不知道这是正确的行为还是表明有问题。

我错过了什么?

19 年 3 月 12 日晚上 7 点半更新:

如上所示并由 sideshowbarker 在评论中指出,有一个“405 Method Not Allowed”响应。起初我认为这与 CORS 问题以及 Nginx 相关。为了验证这一点,我停止了 Nginx,并在端口 12345 上打开了防火墙,以便我可以直接 POST 到 Golang 后端。

为了避免同源策略带来的任何复杂化,我使用 cURL 从另一台机器进行 POST:curl -v -X POST -H 'Content-Type: application/json' -d '{"age":"l","性别":"l","问题":"l"}' http://droplet_IP:12345/anteroom

我得到了完全相同的响应:“不允许使用 HTTP/1.1 405 方法”。

在这一点上,我最好的猜测是 Golang 后端不允许 POST,即使它在代码中明确允许,如上所示。我不知道为什么。

最佳答案

这个问题主要是由于 Golang 代码中 main() 中的 Gorilla mux 这行造成的:

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

注意后面的方法:("POST, OPTIONS")。这是错误的。它应该是 ("POST", "OPTIONS")。它们必须单独引用。

这与我们使用 net/http 在函数中设置方法时不同: res.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") 。在这里,它们被一起引用。

我认为可能存在各种各样的问题,但这是一段非常累人的旅程,我现在只记得最后一个。

关于angular - 405 Method Not Allowed and "CORS header ‘Access-Control-Allow-Origin’ missing“虽然tcpdump说它正在被发送出去,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55111117/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com