即使 Rails 服务器配置为接受所有请求,Angular 发布请求也未通过预检
Posted
技术标签:
【中文标题】即使 Rails 服务器配置为接受所有请求,Angular 发布请求也未通过预检【英文标题】:Angular post request doesnt pass preflight check even though rails server is configured to accept all requests 【发布时间】:2016-05-27 01:32:32 【问题描述】:我正在使用 angularJS 应用程序来请求 Rails API。我从我的角度控制器发送我的 http 请求,但似乎预检请求没有通过访问控制检查:
controller('RegistrationsCtrl',['$scope', '$http', '$ionicLoading',function($scope, $http, $ionicLoading)
$scope.launchReq = function()
$http.post('http://localhost:3333/users', email: "bou@gmail.com", 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' => %wGET POST OPTIONS.join(",")
end
end
但我仍然在客户端收到以下错误:
在服务器端,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'
我还需要在客户端(angular)或服务器(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
似乎代码甚至没有进入应用程序控制器,我仍然收到错误...
【问题讨论】:
【参考方案1】:我设法使用 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
【讨论】:
【参考方案2】:您是否阅读过这里的回复? Rails Responds with 404 on CORS Preflight Options Request
似乎是 Rails 配置问题。
【讨论】:
以上是关于即使 Rails 服务器配置为接受所有请求,Angular 发布请求也未通过预检的主要内容,如果未能解决你的问题,请参考以下文章
jquery ajax post请求不接受绝对url rails应用程序
Ember 应用程序对 Rails 应用程序的请求——跨域?
web api - asp.net 身份令牌即使对于后续请求也会过期