🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

CORS

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

React.js

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

Lumen

PHP Laravel製のマイクロフレームワーク

Q&A

解決済

1回答

3279閲覧

特定のルートのみReact(JavaScript)からLumen(PHP)へAjaxをした際にCORSで弾かれる。

退会済みユーザー

退会済みユーザー

総合スコア0

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

CORS

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

React.js

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

Lumen

PHP Laravel製のマイクロフレームワーク

1グッド

1クリップ

投稿2020/03/12 13:06

編集2020/03/12 15:32

概要

現在下記の様な構成のアプリケーションを開発しています。
構成図

フロントエンドにReact.js、バックエンドにAPIサーバーのLumen、その間にリバースプロキシとしてNginxを置いています。
そこで、ReactからPromiseベースのAjaxライブラリであるaxiosを使ったところCORSで弾かれました。
Lumen側でCORSの設定をし、一応は回避することはできたのですが、特定のページにいくとまたCORSで弾かれます。
画面の遷移にはreact-routerを使用しています。個人的にはwebpack、もしくはnginxの設定が間違っていると考えています。
自分なりに色々調べてみましたが、解決せず…。
どなたか解決方法のご教授お願いいたします。

エラーの内容

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

該当のコード

// nginx server { listen 0.0.0.0:80; server_name localhost; charset utf-8; location / { root /var/www/client/dist; index index.html index.htm; try_files $uri $uri/ /index.html; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin: $http_origin'); add_header 'Access-Control-Allow-Origin: GET, POST, DELETE, PUT, PATCH, OPTIONS'); add_header 'Access-Control-Allow-Credentials: true'); add_header 'Vary: Origin'); } add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always; } # Media: images, icons, video, audio, HTC location ~* .(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; } # ReverseProxy: Lumen API server location ^~ /api { proxy_pass http://127.0.0.1:8000; location ~ .php$ { fastcgi_pass server:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin: $http_origin'); add_header 'Access-Control-Allow-Origin: GET, POST, DELETE, PUT, PATCH, OPTIONS'); add_header 'Access-Control-Allow-Credentials: true'); add_header 'Vary: Origin'); } add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always; } }
// Lumen <?php namespace App\Http\Middleware; use Closure; class CorsMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // TODO:Access-Control-Allow-Originを適切に指定する必要がある $headers = [ 'Access-Control-Allow-Origin' => '*', 'Access-Control-Allow-Methods' => 'POST, GET, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Credentials' => 'true', 'Access-Control-Max-Age' => '86400', 'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With' ]; // preflightリクエスト用 if ($request->isMethod('OPTIONS')) { return response()->json('{"method":"OPTIONS"}', 200, $headers); } $response = $next($request); foreach ($headers as $key => $value) { $response->header($key, $value); } return $response; } }
// webpack.config.js import path from 'path' const src = path.resolve(__dirname, 'src') const dist = path.resolve(__dirname, 'dist') module.exports = { mode: "development", entry: ['@babel/polyfill', src + '/index.js'], output: { path: dist, filename: "main.js" }, module: { rules: [ { // css test: /.css$/, exclude: { include: /node_modules/, // quill.js exclude: /node_modules/react-quill// }, use: [ 'style-loader', { loader: 'css-loader', options: { url: false, }, }, ], }, { // js test: /.js$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: { presets: [['@babel/preset-env', { modules: false }]] } } ] }, { // tsx test: /.tsx?$/, use: "ts-loader", }, { // image test: /.(jpg|JPG|jpeg|png|PING|gif|mp3|svg|ttf|woff2|woff|eot)$/, use: { loader: "file-loader", options: { name: "[name].[ext]", outputPath: "assets/img", publicPath: path => "/assets/img/" + path } } } ] }, resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }, devServer: { contentBase: './dist', host: '0.0.0.0', port: 3000, inline: true, historyApiFallback: true } };

バージョン

Lumen 6.3.3

s.k👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2020/03/12 17:08

関係あるか分かりませんが、nginx の設定ファイルで、 add_header 'Access-Control-Allow-Origin: GET, POST, DELETE, PUT, PATCH, OPTIONS'); という行が 2 箇所ありますが、Access-Control-Allow-Method では?
退会済みユーザー

退会済みユーザー

2020/03/12 17:13

ご回答ありがとうございます! 確かに!ただ、修正いたしましたが、ダメでしたね…。
退会済みユーザー

退会済みユーザー

2020/03/12 17:40

今回は認証にCookieを使用していないですが、一応、変更してみたところダメでした…。 個人的にはLumenは問題ないように思います。(直感ですが…。) webpack、もしくはnginxの設定だと思うんです…。
hoshi-takanori

2020/03/12 17:54

webpack は何の関係もないでしょう。CORS で弾かれる特定のページにどうやってアクセスして、実際にどんなレスポンスが返ってくるかを確認してみるのがいいと思います。
退会済みユーザー

退会済みユーザー

2020/03/12 18:11

なるほど…。 設定ファイルにaccess_log /var/log/nginx/access.log main;を追加し、catコマンドでlogファイルを表示しようとしましたが、何も出力されませんでした。これは通常の挙動なのでしょうか?個人的にはブラウザを更新した瞬間にアクセスログがaccess.logファイルに出力されるイメージなのですが…。
退会済みユーザー

退会済みユーザー

2020/03/12 18:14

そもそも一部の画像の表示もされていない(404)ですし、表示されている画像は、200 OK (from memory cache)となっているのですが、ここら辺は手掛かりになったりしないでしょうか???
hoshi-takanori

2020/03/12 18:34

access_log ファイル名 main; の main は独自フォーマットを設定してるってことでしょうか? いずれにせよ、アクセスログにはすべての情報は出てこないので、curl コマンドとかブラウザの開発者ツールとかで生のリクエストとレスポンスを確認すべきです。 画像のキャッシュは切って試してみるべきでは。access_log を off にする理由もないと思いますし。
退会済みユーザー

退会済みユーザー

2020/03/12 18:47

え、そうなんですね…!まあ、確かにoffにする理由もないですしね。ちなみにキャッシュを消去したところ画像は全て表示されなくなりました。恐らく画像のルーティングも間違っている予感…。正直もうお手上げ状態です…。nginx難しい…!
退会済みユーザー

退会済みユーザー

2020/03/12 18:49

僕のイメージ的にはこの設定で、Reactのaxiosで/apiにアクセスするとlocalhost:8000にリバプロされるイメージなのですが、そもそもそこができていないということはないですよね…?
退会済みユーザー

退会済みユーザー

2020/03/12 18:55

あ、画像に関しては表示される様になりました! 一番下の画像のルーティングを消去したところ表示されました! っていうか、index.htmlを読み込んでいる時点でこのルーティングは不要でしたね…。申し訳御座いません!
退会済みユーザー

退会済みユーザー

2020/03/12 19:05

何度も申し訳御座いません! GET、POSTは反応するのですが、どうやらPUTが反応していないようです!
hoshi-takanori

2020/03/12 19:22

もしかして、React も nginx を経由するようにすれば CORS 不要なのでは。
退会済みユーザー

退会済みユーザー

2020/03/12 19:45

度重なるご回答ありがとうございます! Reactもnginxを経由するとは具体的にどういうことでしょうか? 一応、現在もaxiosを使ってnginxのリバプロ経由でLumen APIにアクセスしていますが、それとはまた別の意味合いでしょうか??
hoshi-takanori

2020/03/12 20:01

現在、index.html, main.js, css などは localhost:3000、api は localhost:80 (nginx) 経由で lumen だと思いますが、最終的には一つのサーバーで全部やるのではと思ったので…。 でも、CORS もちゃんと設定すれば動くはずなので、curl コマンドで API を叩いて、何が帰ってくるかちゃんと確認するのがいいと思います。 https://qiita.com/miminashi/items/f48cd4c25b06fcab5ea3
退会済みユーザー

退会済みユーザー

2020/03/12 20:20

postmanで叩いてみましたが、正常にレスポンスが帰ってきました…。この現象は一体なんなんでしょうか…?
退会済みユーザー

退会済みユーザー

2020/03/12 20:26

正常に動作いたしました!!! php側でエラーが発生していました…。本当に申し訳御座いません…。 ただ、エラーとCORSにどういった関係があるのかが、よくわかりません…。 とりあえず、最後までご丁寧なご対応ありがとうございました!
hoshi-takanori

2020/03/12 20:29

PHP 側でエラーが発生すると、CORS のヘッダーを設定する前にエラーメッセージを出力しちゃうので、ヘッダーが正常に出力されず、CORS エラーってことになるのでしょうね。CORS エラーな時点で中身(エラーメッセージも)は無視されるでしょうし。
guest

回答1

0

ベストアンサー

PHPのエラーを修正したところ正常に動作いたしました!

投稿2020/03/12 20:26

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問