CORS とは
ブラウザで Ajax 通信を行う際、一般的には Same Origin Policy により Web コンテンツを配信するドメイン以外への HTTP リクエストができない。しかし、HTTP(S) で API を叩きたい時等、異なるドメインのリソースに対してアクセスしたい状況は常に発生しうる。
CORS とは Cross-Origin Resource Sharing の略であり、XMLHttpRequest でクロスドメインアクセスを実現するためのものである。例えば Laravel で API を作成し、API をホストするドメインとは異なるドメインからその API を呼び出したい場合は、Laravel 側で対応する必要がある。
対応方法
以下に実際に対応方法を記載する。
ミドルウェアの作成
まずは CORS 対応を行うミドルウェアを作成する。
$ php artisan make:middleware Cors
作成されたミドルウェアを以下のように変更する。
app/Http/Middleware/Cors.php
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
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', 'Content-Type');
}
}
なお、Access-Control-Allow-Origin で呼び出し元のドメインを指定することが可能。どこから呼び出されても良い場合は * を指定し、もしドメインを限定するのであればそのドメインを指定する。
Kernel.php を編集
app/Http/Kernel.php を以下のように編集し、$routeMiddleware に作成したミドルウェアを追加する。
app/Http/Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'cors' => \App\Http\Middleware\Cors::class,
];
route を編集
最後に routes/api.php を編集する。
routes/api.php
<?php
use Illuminate\Http\Request;
Route::middleware(['cors'])->group(function () {
Route::get('list_cases', 'Api\InqueryController@listInqueries');
Route::get('describe_case', 'Api\InqueryController@describeInquery');
Route::get('create_case', 'Api\InqueryController@createInquery');
Route::get('update_case', 'Api\InqueryController@updateInquery');
Route::get('add_correspondence_to_case', 'Api\InqueryController@addCorrespondenceToInquery');
});
以上で完了。
補足
なお、自前でミドルウェアを用意しなくとも、これを利用すればもっと簡単にできるみたいです。