3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravelとjsのfetchの組み合わせで躓いた話

Posted at

何が起きたか

jsでajax通信がしたく以下のように書いた。

fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json; charset=utf-8" },
  body: JSON.stringify(parameters)
})

これで、バリデーションエラーで弾かれた場合、Laravelからはステータスコード422とエラーメッセージが帰ってくるはずだった。
なのに、ステータスコードは405でしかもエラーメッセージは何も帰ってこない。
これの解決に3時間くらいかかってしまったのでここに残しておく。

結論

headersには"X-Requested-With": "XMLHttpRequest"が必要。

解説

結論を見れば分かるかもしれないが、Laravel(正確には拡張元のsymfony)はリクエストヘッダーの上記を見てajaxかどうかを判断している。
なのでこれを入れないと、Laravelは通常のリクエストと判断しフォーム画面に戻すべくRedirectResponseを返す。
これにより、何等かの原因で405というおかしなコードが帰ってきた(この時点でおかしいことは分かったのでこれ以上は詳しくは見ていない)。

実際にソースを追ってみたところ以下のようになっている。

  1. まずここで、バリデーションに引っ掛かった場合はfailedValidation()を実行しValidationExceptionをthrow
  2. 例外ハンドラがValidationExceptionをcatchし、ここでJsonResponseを返すかRedirectResponseを返すかを分岐
  3. expectsJson()ここajax()の結果からajax通信かどうかを見ており
  4. ajax()ここでxmlHttpRequestかを見ており
  5. xmlHttpRequestかはここ"X-Requested-With": "XMLHttpRequest"かを見ている

所感

「laravel fetch 405」とかでググってもヒットしないものだから苦労した。。常識なのだろうか。
常識なのであればこの機会に知ってよかったと思うことにする。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?