这个问题遵循这个 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/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
每次我尝试使用“script/runner-eproductionClassName.run”从我的Rails2.2应用程序的lib目录运行任何类时,我都会收到以下错误:/usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/commands/runner.rb:47:/usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:89:in`const_missing':uninitializedconstantClassName(NameError)
使用Ruby1.8.6/Rails2.3.2我注意到在我的任何ActiveRecord模型类上调用的任何方法都返回nil而不是NoMethodError。除了烦人之外,这还破坏了动态查找器(find_by_name、find_by_id等),因为即使存在记录,它们也总是返回nil。不从ActiveRecord::Base派生的标准类不受影响。有没有办法追踪在ActiveRecord::Base之前拦截method_missing的是什么?更新:切换到1.8.7后,我发现(感谢@MichaelKohl)will_paginate插件首先处理method_missing。但是will_pa
我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案
执行rvmlist后,我得到以下输出:rvmrubiesgems[missingbin/ruby]=*ruby-2.0.0-p645[x86_64]ruby-2.1.6[x86_64]ruby-2.2.1[x86_64]gems[missingbin/ruby]是什么意思?gems是某种系统gemset吗?它不是我创建的,我不知道我是否可以或应该删除它。 最佳答案 在我跑完之后:rvmfix-permissions然后我能够卸载具有[缺少bin/ruby]的版本。 关于ruby-如何修复
我有一个ruby程序,我想接受用户创建的方法,并使用该名称创建一个新方法。我试过这个:defmethod_missing(meth,*args,&block)name=meth.to_sclass我收到以下错误:`define_method':interningemptystring(ArgumentError)in'method_missing'有什么想法吗?谢谢。编辑:我以不同的方式让它工作,但我仍然很好奇如何以这种方式做到这一点。这是我的代码:defmethod_missing(meth,*args,&block)Adder.class_evaldodefine_method