開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. PHP >
  4. Laravel >
  5. Laravel/Inertia.jsをCloudFrontを使ったインフラ構成で構築する場合のハマりポイント

Laravel/Inertia.jsをCloudFrontを使ったインフラ構成で構築する場合のハマりポイント

こんにちは。
ニシザワです。


本日は、Laravel+InertiaでAWSのCloudFrontを使った時のハマりポイントを説明します。
本ブログではLaravelやInertia.jsのインストール方法は説明しません

環境

Laravel:10.x
inertiajs/inertia-laravel:0.6.9
inertiajs/react:18.0.X

ハマりポイント

InertiaのuseFormを使ってPOSTやGETのリクエストを送ります。
期待する動作としては、ページが表示されるはずですよね。
CloudFrontを経由すると、画面が表示されなかったり、思わないページに遷移したりします。

解決策

結論、CloudFrontの設定でHTTPリクエストのカスタムヘッダーをキャッシュキーに設定し、オリジンリクエストのヘッダーにもカスタムヘッダーが含まれるようにしましょう。
Inertia.jsは極力HTMLは返さず、対象のComponentと必要な情報の差分を返すようになっているため
HTTPリクエストヘッダーにX-InertiaX-Inertia-Version,X-Requested-Withが必要になります。
AWSのCloudFrontは余計なHTTPリクエストヘッダーを通さない様になっているため上記追加が必要になってきます。

CloudFrontのビヘイビアからカスタムヘッダーを追記してみましょう。

スクリーンショット 2023-08-04 13.28.00.png
 

もう一つのハマりポイント

ここまでは、探せば出てきますが、もう一つハマりポイントがあります。
参考
それは、バリデーションエラーを発生させたときです。
この時、期待する動作は画面にバリデーションエラーが表示されるはずですが、何故かjsonのレスポンスが返ってきてしまいます。
InertiaのuseFormは非同期の処理を内部的に行っており、JSONを返すAPIにアクセスしているような振る舞いをします。
HTTPリクエストヘッダーを見ると、X-Requested-With:XMLHttpRequest,Content-Type:application/jsonになっていることがわかるでしょう。
また、Accept:text/html, application/xhtml+xmlになっています。
ここで見えてくるのが、inertia.fromは非同期でAPI通信をしているが、ResponseはHTMLを要求していることです。
CloudFrontを通すと、jsonが返ってきます。
何故かというと、LaravelがレスポンスをJSONで返すべきかどうかの判定にHTTPリクエストヘッダーのAcceptが関係しているからです。
CloudFrontのカスタムヘッダーにAcceptが無いと、Accept:*/*がリクエスト時にWebサーバーへ送られるため
X-Requested-With:XMLHttpRequestの判定のみとなり、JSONでレスポンスを返すべきリクエストと判定されてしまっています。
ですので、CloudFrontのカスタムヘッダーにAcceptも追加しないといけません。

スクリーンショット 2023-08-04 13.28.22.png
 

まとめ

CloudFront+Laravel/Inertia.jsを使った、アプリケーションを構築する時は
ビヘイビアのカスタムヘッダーに
  • X-Inertia
  • X-Inertia-Version
  • X-Requested-With
  • Accept
を追加しましょう。
Laravel/Inertia.jsの構成はこれから色々と機能が拡充されていくと思うので楽しみにしてます。
TOPに戻る