【问题标题】:XMLHttpRequest No 'Access-Control-Allow-Origin' header is present on the requested resourceXMLHttpRequest 请求的资源上不存在“Access-Control-Allow-Origin”标头
【发布时间】:2014-09-22 14:49:41
【问题描述】:

因此,在 StackOverflow 上存在一些解决此错误的问题,但在我检查的 10-15 个问题中,我找不到确切问题的解决方案。

我正在远程服务器上运行 Angular 应用程序(端口 9000)和 Rails 应用程序(端口 3000)。 Angular 应用通过 post 请求向 Rails 应用发送请求。

发出请求时,Javascript 控制台会显示以下错误消息:

XMLHttpRequest cannot load http://0.0.0.0:3000/api/query. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://10.241.16.159:9000' is therefore not allowed access. 

根据我的阅读,我需要更改我的 Rails 应用程序的一些内容,以便它可以接受来自其他服务器的连接(这似乎很奇怪,因为两个应用程序都在同一个 ec2 实例上运行)。

我尝试添加类似的行

  skip_before_filter :verify_authenticity_token

到我在rails中的控制器,但这似乎没有效果。

我该如何解决这个错误?

【问题讨论】:

  • 它们都在同一个 EC2 实例上并不重要。它们在不同的端口上,CORS 专门针对被命中的 URL,由于它们都在不同的端口上,它们是不同的 url 试试这个:leopard.in.ua/2012/07/08/using-cors-with-rails
  • 有没有办法让我的 Rails 服务器接受所有 CORS 请求,即使是以牺牲一些安全性为代价?
  • 不确定如何在 Rails 中执行此操作,但是当我在 PHP 上遇到这个问题时,我不得不在我的 php 文件中添加一些标题行:header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
  • 你试过这个headers['Access-Control-Allow-Origin'] = request.headers["HTTP_ORIGIN"]
  • 我应该在哪里包含该代码,hex494D49?

标签: javascript ruby-on-rails angularjs


【解决方案1】:

试试这个代码

  <httpProtocol>
          <customHeaders>
           <add name="Access-Control-Allow-Origin" value="*" />
           <add name="Access-Control-Allow-Headers" value="Content-Type" />
           <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS"/>
          </customHeaders>
     </httpProtocol>

inside the <system.webServer> 

【讨论】:

    【解决方案2】:

    如果你还没有读到它,让我告诉你问题是什么......

    您的应用程序的 CORS policy 有问题

    --

    CORS(Corss 源资源共享)

    当您使用 XHR (XML HTTP REQUEST) 访问另一台服务器上的 endpoint 时,您的应用程序(尽管我不确定如何)将默认拒绝访问请求的资源。

    发生这种情况的原因是为了确保只有某些数据/资源可以通过 XHR 获得,这也是它主要用于 API 之类的原因。

    --

    机架-CORS

    无论如何,您需要允许在 Rails 应用程序中访问您的 Java 应用程序 - 我个人建议使用 rack-CORS gem:

    #Gemfile
    gem 'rack-cors'
    
    #config/application.rb
    config.middleware.use Rack::Cors do
       allow do
         origins '*'
         resource 'api/jquery', :headers => :any, :methods => [:get, :post]
       end
    end
    

    这将“允许”来自不同应用程序的请求,为您解决问题。

    【讨论】:

    • 行资源'api/jquery'是什么意思?如果我想使用 angularjs 中的 $http 而不是 jquery 中的 $.post,我应该保留这条线吗?我仍然从 jquery 和 angular 中得到同样的错误。
    【解决方案3】:

    在 app/controllers/application_controller.rb 中:

    before_filter :add_allow_credentials_headers
    
    def add_allow_credentials_headers                                                                                                                                                                                                                                                        
      # https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#section_5                                                                                                                                                                                                      
      #                                                                                                                                                                                                                                                                                       
      # Because we want our front-end to send cookies to allow the API to be authenticated                                                                                                                                                                                                   
      # (using 'withCredentials' in the XMLHttpRequest), we need to add some headers so                                                                                                                                                                                                      
      # the browser will not reject the response                                                                                                                                                                                                                                             
      response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] || '*'                                                                                                                                                                                                     
      response.headers['Access-Control-Allow-Credentials'] = 'true'                                                                                                                                                                                                                          
    end 
    
    def options                                                                                                                                                                                                                                                                              
      head :status => 200, :'Access-Control-Allow-Headers' => 'accept, content-type'                                                                                                                                                                                                         
    end
    

    在 config/routes.rb 中:

    match '*any' => 'application#options', :via => [:options]
    

    注意,如果您的 Angular 前端正在执行 POST 请求,这是对您将需要的 OPTIONS 请求的响应。我对 Access-Control-Allow-Credentials 所做的一点是针对我的应用程序,因此 cookie 是从前端发送的。

    我强烈建议您阅读我上面代码中那个 mozilla 链接中的文档。它对CORS有非常透彻的解释。您可能会发现上面的代码对于您的目的来说过于宽松。

    【讨论】:

    • 为什么这样可以解决问题?我将此添加到我的应用程序控制器中,现在我的客户端框架应用程序现在可以使用此 api。
    猜你喜欢
    • 2015-04-04
    • 2017-08-20
    • 2017-04-28
    • 2019-10-24
    • 2013-11-29
    • 2014-07-28
    • 2014-01-19
    相关资源
    最近更新 更多