Laravel で React/API を別プロジェクトで作った際、axios を使ったクロスドメインに少し困ったのでメモ。
Access-Control-Allow-Origin エラー
フロントが出すエラーとしては、以下のようなもの。
No 'Access-Control-Allow-Origin' header is present on the requested resource.
原因はAPI側が自身と異なるホストからのアクセスを許可していないから。
なのでAPIのレスポンスヘッダーに許可する設定を加えれば良い。
以下、解決手順はすべてAPI側の設定。
ヘッダーを追加する
方法1: barryvdh/laravel-cors を使う
方法2:コントローラでレスポンス毎に追記
// XXXController.php + header('Access-Control-Allow-Origin', '*') + header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Requested-With'); + header('Access-Control-Allow-Credentials: true'); return response()->json($data);
方法3: 自前ミドルウェア追加
参考) Adding Access-Control-Allow-Origin header response in Laravel 5.3 Passport - Stack Overflow
$ php artisan make:middleware Cors
app/Http/Middleware/Cros.php
public function handle($request, Closure $next) { return $next($request) ->header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') ->header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Requested-With') ->header('Access-Control-Allow-Credentials: true'); }
app/Http/Kernel.php > $routedMiddleware
'cors' => \App\Http\Middleware\Cors::class,
routes/web.php
Route::group(['middleware' => ['cors'], 'prefix' => 'api'], function ($router) { // routes here ... });
routeの見直し
routes/web.php
- Route::get("hoge", "HogeController@show"); + Route::match(["get", "options"], "hoge", "HogeController@show");
Laravel React で axios を使ってAPIにリクエストを送ると HTTPメソッドが options 形式になっていたので、API側のルートもoptionsを受け付けるように見直し。
こんな感じで無事クロスドメインができた。
方法3の自前ミドルウェアが一番メンテナンス楽そうだと思った。