javascript CORS 问题:实际出现错误“不存在‘Access-Control-Allow-Origin’标头”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20724470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CORS issue: Getting error "No 'Access-Control-Allow-Origin' header is present" when it actually is
提问by chadoh
I doubt the backend serving my app is important, but if you care, I'm using rack-corswith a Rails 4.0 app.
我怀疑为我的应用程序提供服务的后端是否重要,但如果您关心,我正在使用带有 Rails 4.0 应用程序的rack-cors。
Using jQuery, I send my app a PATCH
request like so:
使用 jQuery,我向我的应用程序发送一个PATCH
请求,如下所示:
$.ajax({
url: "http://example.com/whatever",
type: "PATCH",
data: { something: "something else" }
})
When I trigger this call from Chrome, I see a successful OPTIONS
request go out, which returns these headers from my server:
当我从 Chrome 触发这个调用时,我看到一个成功的OPTIONS
请求发出,它从我的服务器返回这些标头:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:accept, content-type
Access-Control-Allow-Methods:GET, PUT, PATCH, OPTIONS
Access-Control-Allow-Origin: http://sending-app.localhost:3000
Access-Control-Expose-Headers:
Access-Control-Max-Age:15
Then I see a PATCH
request go out, which throws this error:
然后我看到一个PATCH
请求出去,它抛出这个错误:
XMLHttpRequest cannot load http://example.com/whatever. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://sending-app.localhost:3000' is therefore not allowed access.
XMLHttpRequest 无法加载http://example.com/whatever。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问Origin ' http://sending-app.localhost:3000'。
I have tried switching from PATCH
to PUT
with the same results.
我尝试从 切换PATCH
到PUT
具有相同的结果。
This doesn't make any sense to me. What's going on?
这对我来说没有任何意义。这是怎么回事?
Update: My config/application.rb
更新:我的 config/application.rb
I thought the headers told the whole story, but since people are confused, here's my config/application.rb
file, which is how the rack-cors plugin for Rails is configured:
我认为标题说明了整个故事,但由于人们感到困惑,这是我的config/application.rb
文件,这是 Rails 的 rack-cors 插件的配置方式:
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '*',
:headers => :any,
:methods => [:get, :put, :patch, :options],
:max_age => 15
end
end
采纳答案by brandonhilkert
Exclude Rails CSRF checking in the action ;)
在操作中排除 Rails CSRF 检查;)
That is, Rails checks for an authenticity token with update/create requests. Within your Rails app, this token is added to all of your forms. But with javascript requests, including it is tricky.
也就是说,Rails 通过更新/创建请求检查真实性令牌。在您的 Rails 应用程序中,此令牌会添加到您的所有表单中。但是对于 javascript 请求,包括它是很棘手的。
You can skip checking it for an action by adding this to your controller:
您可以通过将其添加到您的控制器来跳过检查它的操作:
skip_before_filter :verify_authenticity_token, :only => [:update]
BTW, your problem had nothing to do with CORS, you were getting a bad error message in the browser. The Rails log tells the realstory.
顺便说一句,您的问题与 CORS 无关,您在浏览器中收到了错误的错误消息。Rails 日志讲述了真实的故事。
回答by Richard Peck
You might want to add this to your config/application.rb
file:
您可能希望将此添加到您的config/application.rb
文件中:
#config/application.rb
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '/*', :headers => :any, :methods => :patch
end
end
The resource
part is where you define which methods / requests your endpoint can accept!
这resource
部分是您定义端点可以接受哪些方法/请求的地方!
Hope this helps
希望这可以帮助
回答by Parris
This is some strange stuff.
这是一些奇怪的东西。
A) As a trial you should try entering in *
as your allowed origin.
A) 作为试用,您应该尝试*
以您允许的来源身份进入。
B) Is this a whitespace issue? After the colons you don't have spaces in some of the options.
B)这是一个空格问题吗?在冒号之后,您在某些选项中没有空格。
C) This looks like a "preflighted request" (https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS). A preflighted request is one that doesn't use "application/x-www-form-urlencoded," which yours should be. http://api.jquery.com/jquery.ajax/states the default content type is x-www-form-urlencoded, and you aren't overriding content type. That means there shouldn't need to be 2 requests.
C)这看起来像一个“预检请求”(https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS)。预检请求是不使用“application/x-www-form-urlencoded”的请求,您应该使用“application/x-www-form-urlencoded”。http://api.jquery.com/jquery.ajax/声明默认内容类型是 x-www-form-urlencoded,并且您没有覆盖内容类型。这意味着不需要有 2 个请求。
D) As noted above, CSRF might be the issue. I am not a rails person. If it is the issue what you may want to do is attach your CSRF token to all ajax sends like so:
D) 如上所述,CSRF 可能是问题所在。我不是铁路人。如果这是您可能想要做的问题是将您的 CSRF 令牌附加到所有 ajax 发送,如下所示:
$.ajaxSetup({
beforeSend:function(xhr, settings){
xhr.setRequestHeader('X-CSRF-Token', '<%= csrf_token_value %>');
}
});
There are a few other ways to do this. It depends what your frameworks/libraries need.
还有其他一些方法可以做到这一点。这取决于您的框架/库需要什么。
回答by Myk Klemme
Here is what I found to solve the issue from older SO posts to deal with csrf issues:
这是我从较旧的 SO 帖子中发现的解决 csrf 问题的方法:
# In application_controller.rb
protect_from_forgery
after_filter :set_csrf_cookie
def set_csrf_cookie
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
protected
# In Rails 4.2 and above
def verified_request?
super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
end