63796


## 概要

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

[![構成図](https://i.stack.imgur.com/KlMDm.png)](https://i.stack.imgur.com/KlMDm.png)

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

## エラーの内容

[code]

    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.
    
[/code]

## 該当のコード

[code]

    // nginx
    
    server {
        listen       0.0.0.0:80;
        server_name  localhost;
        charset      utf-8;
    
        # Root
        location / {
            root    /var/www/client/dist;
            index   index.html index.htm;
            try_files $uri $uri/ /index.html;
            access_log /var/log/nginx/access.log;
            error_log  /var/log/nginx/error.log;
    
            if ($request_method = 'OPTIONS') {
              add_header 'Access-Control-Allow-Origin: $http_origin');
              add_header 'Access-Control-Allow-Methods: 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;
        }
    
        # ReverseProxy: Lumen API server
        location /api {
            proxy_pass http://127.0.0.1:8000;
            access_log /var/log/nginx/access.log;
            error_log  /var/log/nginx/error.log;
    
            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-Methods: 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;
        }
    }
    
[/code]

[code]

    // 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;
        }
    }
    
[/code]

[code]

    // 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
        }
    };
    
[/code]

## バージョン

Lumen 6.3.3


CC BY-SA 4.0
2020-03-12T13:03:29.323
63795
2021-04-04T00:54:49.217
2021-04-04T00:54:49.217
32986
32711
question
php laravel nginx reactjs axios
特定のルートのみReact(JavaScript)からLumen(PHP)へAjaxをした際にCORSで弾かれる。


PHPのエラーを修正したところ正常に動作いたしました！ありがとうございました！  
原因としては、PHP 側でエラーが発生すると、CORS のヘッダーを設定する前にエラーメッセージを出力しちゃうので、ヘッダーが正常に出力されず、CORS
エラーってことになる感じですかね…！CORS エラーな時点で中身（エラーメッセージも）は無視されるでしょうし。  
因みにPHP側のエラーとしては存在しないクラスを使用していました。


CC BY-SA 4.0
2020-03-12T20:27:11.630
63796
2020-03-13T23:29:00.700
2020-03-13T23:29:00.700
32711
32711
63795
answer