即使rails服务器配置为接受所有请求,Angular post请求也不会通过预检检查

问题描述 投票:5回答:2

我正在使用angularJS应用程序来请求rails API。我从我的角度控制器发送我的http请求,但似乎预检请求没有通过访问控制检查:

controller('RegistrationsCtrl',['$scope', '$http', '$ionicLoading',function($scope, $http, $ionicLoading) {
  $scope.launchReq = function(){
    $http.post('http://localhost:3333/users', {email: "[email protected]", password: "12345678"}).success(function(data){
      console.log(data);

      }).error(function(err){
       // $ionicLoading.hide();
       if (err.error == "Uncomfirmed account"){
          $scope.err = "Ce compte n'a pas été confirmé.<a href="+"'"+"/#/phoneConfirmation/"+err.user_id+"'"+">Obtenir votre code de confirmation ?</a>"
        }
       else {
          $scope.err = "Identifiant ou mot de passe incorrect.";
        }
     });
  }
}])

我已经尝试通过按照建议here设置我的application.rb文件来配置我的rails服务器:

require File.expand_path('../boot', __FILE__)

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module QuickBedApi
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Do not swallow errors in after_commit/after_rollback callbacks.
    config.active_record.raise_in_transactional_callbacks = true
    config.action_dispatch.default_headers = {
      'Access-Control-Allow-Origin' => 'http://localhost:8100',
      'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",")
    }
  end

end

但我仍然在客户端遇到以下错误:

enter image description here

在服务器端,似乎rails API不理解OPTIONS是预检调用,因为我收到路由错误:

Started OPTIONS "/users" for ::1 at 2016-02-16 00:30:09 +0100
  ActiveRecord::SchemaMigration Load (0.6ms)  SELECT "schema_migrations".* FROM "schema_migrations"

ActionController::RoutingError (No route matches [OPTIONS] "/users"):
  actionpack (4.2.5) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.5) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `call'
  quiet_assets (1.1.0) lib/quiet_assets.rb:27:in `call_with_quiet_assets'
  actionpack (4.2.5) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
  rack (1.6.4) lib/rack/runtime.rb:18:in `call'
  activesupport (4.2.5) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
  rack (1.6.4) lib/rack/lock.rb:17:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/static.rb:116:in `call'
  rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
  railties (4.2.5) lib/rails/engine.rb:518:in `call'
  railties (4.2.5) lib/rails/application.rb:165:in `call'
  rack (1.6.4) lib/rack/content_length.rb:15:in `call'
  puma (2.15.3) lib/puma/server.rb:541:in `handle_request'
  puma (2.15.3) lib/puma/server.rb:388:in `process_client'
  puma (2.15.3) lib/puma/server.rb:270:in `block in run'
  puma (2.15.3) lib/puma/thread_pool.rb:106:in `call'
  puma (2.15.3) lib/puma/thread_pool.rb:106:in `block in spawn_thread'

我还需要在客户端(角度)或服务器(rails)端配置以确保跨源请求正常工作吗?

编辑

我也试过像这样更新我的application_controller:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  skip_before_filter  :verify_authenticity_token
  before_filter :cors_preflight_check
  after_filter :cors_set_access_control_headers

  def cors_set_access_control_headers
     headers['Access-Control-Allow-Origin'] = '*'
     headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
     headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token'
     headers['Access-Control-Max-Age'] = "1728000"
   end

   def cors_preflight_check
    binding.pry
     if request.method == 'OPTIONS'
       headers['Access-Control-Allow-Origin'] = '*'
       headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
       headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token'
       headers['Access-Control-Max-Age'] = '1728000'
       render :text => '', :content_type => 'text/plain'
     end
   end

end

似乎代码甚至没有进入应用程序控制器,我仍然得到错误...

ruby-on-rails angularjs post cross-domain preflight
2个回答
3
投票

我设法使用gem rack-cors https://github.com/cyu/rack-cors使其工作。安装gem之后,你必须更新你的config/application.rb

 config.middleware.insert_before 0, "Rack::Cors" do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

你仍然需要application.rb中的以下方法:

 before_filter :cors_preflight_check
  after_filter :cors_set_access_control_headers

  def cors_set_access_control_headers
     headers['Access-Control-Allow-Origin'] = '*'
     headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
     headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token'
     headers['Access-Control-Max-Age'] = "1728000"
   end

   def cors_preflight_check
    binding.pry
     if request.method == 'OPTIONS'
       headers['Access-Control-Allow-Origin'] = '*'
       headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
       headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token'
       headers['Access-Control-Max-Age'] = '1728000'
       render :text => '', :content_type => 'text/plain'
     end
   end

0
投票

你在这里看过回答吗? Rails Responds with 404 on CORS Preflight Options Request

似乎是rails配置问题。

© www.soinside.com 2019 - 2024. All rights reserved.