質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

CORS

CORSとはCross-Origin Resource Sharingの頭文字をとったもので、ブラウザがオリジン以外のサーバからデータを取得するシステムのことです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

解決済

【rails, nginx】cors の設定をしているのに「No 'Access-Control-Allow-Origin' header is present 」になる

gozikyu
gozikyu

総合スコア4

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

CORS

CORSとはCross-Origin Resource Sharingの頭文字をとったもので、ブラウザがオリジン以外のサーバからデータを取得するシステムのことです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

2回答

0評価

1クリップ

2673閲覧

投稿2021/05/27 10:46

編集2021/05/29 06:51

アプリ環境
・フロントエンドにreact ポート80
・バックエンドにrails-api
・nginxでリクエストを受け取りrails-apiに転送 ポート3001
・docker-composeでdocker上に環境構築

イメージ説明

困っていること
rails, nginxにcorsの設定をしている、具体的にはoriginにhttp://localhostを指定しているのですが、以下のように
Access-Control-Allow-Originのヘッダーがないというエラーが出てしまいます。

Access to XMLHttpRequest at 'http://localhost:3001/login' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

自分でも現在原因調査中なのですが、なにかアドバイスある方いらっしゃいましたら助言いただけると幸いです。
よろしくお願いいたします。

以下に関係すると思われるファイルを記述しています。

docker-compose.yml

version: "3" services: app: build: context: ./api/ dockerfile: Dockerfile env_file: - ./api/environments/db.env command: bundle exec puma -C config/puma.rb volumes: - ./api:/webapp - public-data:/webapp/public - tmp-data:/webapp/tmp - log-data:/webapp/log depends_on: - db db: image: mysql:8.0 env_file: - ./api/environments/db.env volumes: - db-data:/var/lib/mysql web: build: context: ./api/containers/nginx dockerfile: Dockerfile volumes: - public-data:/webapp/public - tmp-data:/webapp/tmp ports: - 3001:80 front: build: context: ./front/ dockerfile: Dockerfile volumes: - ./front:/usr/src/app command: sh -c "cd react_front && npm start " ports: - "80:3000" volumes: public-data: tmp-data: log-data: db-data:

config/application.rb

require_relative 'boot' require 'rails' # Pick the frameworks you want: require 'active_model/railtie' require 'active_job/railtie' require 'active_record/railtie' require 'active_storage/engine' require 'action_controller/railtie' require 'action_mailer/railtie' require 'action_mailbox/engine' require 'action_text/engine' require 'action_view/railtie' require 'action_cable/engine' # 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 Myapp class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 6.1 # Configuration for the application, engines, and railties goes here. # # These settings can be overridden in specific environments using the files # in config/environments, which are processed later. # # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") # Only loads a smaller set of middleware suitable for API only apps. # Middleware like session, flash, cookies can be added back manually. # Skip views, helpers and assets when generating a new resource. config.api_only = true config.middleware.insert_before 0, Rack::Cors do allow do origins 'http://localhost', 'https://condots.net' resource '*', headers: :any, methods: %i[get post patch delete options], credentials: true end end config.hosts << '.example.com' config.hosts << '3.112.0.252' config.hosts << 'condots.net' config.hosts << 'localhost' # セッションメソッドを有効にする config.middleware.use ActionDispatch::Cookies config.middleware.use ActionDispatch::Session::CookieStore config.middleware.use ActionDispatch::ContentSecurityPolicy::Middleware config.time_zone = 'Tokyo' config.active_record.default_timezone = :local config.action_dispatch.default_headers = { 'Access-Control-Allow-Credentials' => 'true', 'Access-Control-Allow-Origin' => if Rails.env.production? 'https://condots.net' else 'http://localhost' end, 'Access-Control-Request-Method' => '*' } end end

config/initializers/cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'http://localhost' resource '*', headers: :any, methods: %i[get post put patch delete options head], credentials: true end end

nginxのDockerfile

FROM nginx:1.15.8 # インクルード用のディレクトリ内を削除 RUN rm -f /etc/nginx/conf.d/* # Nginxの設定ファイルをコンテナにコピー ADD nginx.conf /etc/nginx/conf.d/webapp.conf # ビルド完了後にNginxを起動(デーモンをオフにしてフォアグラウンドで実行) CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

nginx.conf

# プロキシ先の指定 # Nginxが受け取ったリクエストをバックエンドのpumaに送信 upstream webapp { # ソケット通信したいのでpuma.sockを指定 server unix:///webapp/tmp/sockets/puma.sock; } server { listen 80; # ドメインもしくはIPを指定 server_name localhost; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # ドキュメントルートの指定 root /webapp/public; client_max_body_size 100m; error_page 404 /404.html; error_page 505 502 503 504 /500.html; try_files $uri/index.html $uri @webapp; keepalive_timeout 5; # リバースプロキシ関連の設定 location @webapp { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://webapp; add_header Access-Control-Allow-Origin http://localhost; if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin http://localhost; add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE'; add_header Access-Control-Allow-Headers 'Origin, Authorization, Accept, Content-Type'; add_header Access-Control-Max-Age 3600; add_header Content-Type 'text/plain charset=UTF-8'; add_header Content-Length 0; return 204; } } }

リクエストを送ったときにheaderを追加
イメージ説明
イメージ説明

変更を反映するためにdocker imagesをdocker-compose build で作り直したあとのheader
イメージ説明

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

ockeghem
ockeghem

2021/05/28 00:06

こういう時はアウトプットの現物を確認する必要があります。少なくともAPIが返すレスポンスヘッダが意図通りのヘッダがついていることを確認してください。エラーが出ている以上は、正しいヘッダでないはずです。それを追記してください。
gozikyu
gozikyu

2021/05/29 02:42

ockeghemさん コメントありがとうございます。 ブラウザの開発者ツールのnetworkからのheader情報を追記しました。
ockeghem
ockeghem

2021/05/29 03:23

Access-Control-Allow-Origin ヘッダがないので、まずはAccess-Control-Allow-Originを出力する必要がありますね。Access-Control-Allow-Credintials: true も必要だと思います。
gozikyu
gozikyu

2021/05/29 06:54

dockerに環境構築をしていたのですが、corsの設定がimagesに反映されていなかったので、docker-compose build --no-cache で一からimageを作り直したら解決しました。 私の検証不足でお手数おかけして申し訳ありませんでした。 ただ、現物のheaderを確認するという方法は勉強になりました。ありがとうございます。 今後も同様のエラーが出たときの検証方法の1つとして参考にさせていただきます。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

CORS

CORSとはCross-Origin Resource Sharingの頭文字をとったもので、ブラウザがオリジン以外のサーバからデータを取得するシステムのことです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。