Help us understand the problem. What is going on with this article?

Rails APIでクロスドメインとpre-flight対応

More than 3 years have passed since last update.

localでRails APIとWebクライアントを別途立てていた時に、クロスドメインとpre-flightへの対応が必要になりました。
Rails APIサーバ: localhost:3000
Webフロントエンド: localhost:3355

Webフロントエンドでは、HTTPクライアントとしてaxiosを利用しました。

クロスドメイン対応

クロスドメイン対応が無い場合、リクエストで"No 'Access-Control-Allow-Origin' header is present on the requested resource." とエラーが出ます

スクリーンショット 2017-03-06 17.46.37.png

localhost:3355からのアクセスに対して、クロスドメイン対応をいれます。

config/application.rb
config.action_dispatch.default_headers = {
  'Access-Control-Allow-Credentials' => 'true',
  'Access-Control-Allow-Origin' => 'http://localhost:3355',
  'Access-Control-Request-Method' => '*'
}

未検証ですが、下記gemではrackレベルで対応可能のようです。
cyu/rack-cors

参考

Rails4アプリに対してクロスドメインでAjaxでCookieを送信したい場合

pre-flight対応

axiosは異なるオリジンに対してリクエストする時に、OPTIONSメソッドでpre-flightのリクエストを送信します。
How to disable OPTIONS request?

OPTIONSメソッドでリクエストしようとして404になります
スクリーンショット 2017-03-06 17.57.59.png

Railsサーバは以下のようなエラーが出ます

Started OPTIONS "/user_token" for ::1 at 2017-03-06 17:57:46 +0900
  ActiveRecord::SchemaMigration Load (3.9ms)  SELECT `schema_migrations`.* FROM `schema_migrations`

ActionController::RoutingError (No route matches [OPTIONS] "/user_token"):

Railsでのpreflightリクエストの実装およびテスト例の実装を参考に実装してみます。

routes.rbの先頭でOPTIONSメソッドでのリクエストに対して、options_requests_controllerをルーティングします。

config/routes.rb
Rails.application.routes.draw do
  match '*path' => 'options_request#preflight', via: :options
  # other resources
end

ヘッダに'Access-Control-Max-Age', 'Access-Control-Allow-Headers', 'Access-Control-Allow-Methods' をつけて返します。

app/controllers/options_request_controller.rb
class OptionsRequestController < ApplicationController
  ACCESS_CONTROL_ALLOW_METHODS = %w(GET OPTIONS).freeze
  ACCESS_CONTROL_ALLOW_HEADERS = %w(Accept Origin Content-Type Authorization).freeze

  def preflight
    set_preflight_headers!
    head :ok
  end

  private

  def set_preflight_headers!
    response.headers['Access-Control-Max-Age'] = ACCESS_CONTROL_MAX_AGE
    response.headers['Access-Control-Allow-Headers'] = ACCESS_CONTROL_ALLOW_HEADERS.join(',')
    response.headers['Access-Control-Allow-Methods'] = ACCESS_CONTROL_ALLOW_METHODS.join(',')
  end
end
shimpeiws
Ruby, Rails / JavaScript, React, Vue.js / Go / AWS, GCP
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした