Symfony の JsonResponse
にはデフォルトで CORS 回避などに使われる jsonp にデフォルトで対応してい、Laravel もまたそれに対応している。
書き方
JsonResponse
の setCallback
を自分で呼び出してやる場合
1 |
response()->json($data)->setCallback('callback'); |
format: json((array|Object) $data = [], int $status = 200, array $headers = [], int $options = 0)->setCallback(string $callback)
Response::jsonp
を使う場合
1 |
response()->jsonp('callback', $data); |
なお、このメソッドは実質的に上の記法のエイリアスであるので、コールバックが一番前に来るだけである。あとすこしコードが短くなる。
Note
指定する(される)コールバックはJSの予約語と一致していないか、関数・変数名として使用できる名前かがチェックされ、不正な場合は InvalidArgumentException('The callback name is not valid.')
が投げられる。
Content-Type
ヘッダーは自動的に text/javascript
がセットされる。
また、コールバックとして null
が渡されると通常のJSONレスポンスとなるため、常に $request->query('callback')
のような形でコールバックを渡せるようにしておけばリクエストに応じて JSON / JSONP を自動的に切り替えられるので割りと便利。
setCallback
は JsonpResponse
が持っているので複数・すべてのJSONを返すエンドポイントで JSONP を利用できるようにする場合はMiddlewareにしてしまうといい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php namespace App\Http\Middleware; use Closure; use Symfony\Component\HttpFoundation\JsonResponse; class AutoJsonP { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $response = $next($request); if ($response instanceof JsonResponse) { $response->setCallback($request->query('callback')); } return $response; } } |