4
5

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さんはどうやってAJAXかどうか区別してバリデーションエラーレスポンスでJSONを返してくるの?

Last updated at Posted at 2020-06-04

はじめに

我らがBOOM TECH CAFEの若きエース、 @miriwo さんの最新記事「Laravel API データポスト時のバリデーションで弾かれた後、http://127.0.0.1:8000/にリダイレクトしてしまう」を読んで、「おや? ワイのLaravelちゃんはAJAXでアクセスすると普通にバリデーションエラーのJSON返してくるんやが……?」と思って、調べてみました。

そもそもAJAXかどうかどうやって判定しているの?

Laravelの公式ドキュメント日本語訳にはこんなふうに書かれてるわけですよ。
https://readouble.com/laravel/5.5/ja/validation.html

※一応、Laravel5.5での話をしていますが、後方バージョンでもだいたい同じだと思います。

伝統的なHTTPリクエストの場合は、リダイレクトレスポンスが生成され、一方でAJAXリクエストにはJSONレスポンスが返されます。

ほうほう、そうなんすね。
んで、AJAXリクエストか伝統的なHTTPリクエストかどうかはどこで判別してるねんと言うと、ここなわけです。

vendor/laravel/framework/src/Illuminate/Http/Request.php(226-234)
    /**
     * Determine if the request is the result of an AJAX call.
     *
     * @return bool
     */
    public function ajax()
    {
        return $this->isXmlHttpRequest();
    }
vendor/symfony/http-foundation/Request.php(1820-1833)
    /**
     * Returns true if the request is a XMLHttpRequest.
     *
     * It works if your JavaScript library sets an X-Requested-With HTTP header.
     * It is known to work with common JavaScript frameworks:
     *
     * @see http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
     *
     * @return bool true if the request is an XMLHttpRequest, false otherwise
     */
    public function isXmlHttpRequest()
    {
        return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
    }

なるほど、つまりRequest Headerに X-Requested-With: XMLHttpRequest ってのが入ってたらAJAXリクエストとして扱うってわけね……え、そんなHeaderどこで入れてたっけ……?

そして我々は X-Requested-With を求めて旅に出た

ソースグレップするとこんなところにいるのを見つけます。

resources/assets/js/bootstrap.js(16-24)
/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

なるほど、axiosのHeaderにデフォルトで入るようにしてるのね……え、でもBootstrap使ってないんやが……
そこで、肝心のAJAXしてるjsをのぞいてみると……

require('./bootstrap');

バッチリrequireしてたーーーーーー!!

やー、無意識って怖いっすね。今回はいい勉強になりました。

4
5
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
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?