10.

jQuery Ajax 完全ガイド — 通信から fetch 移行まで

編集
この記事の要点
  • jQuery Ajax$.ajax() / $.get() / $.post() / $.getJSON() / $.load() の 5 系統
  • 現代の jQuery (1.5+) は Promise (jqXHR) を返し .done() / .fail() / .always() / .then() で連結
  • CSRF 対策: Laravel は X-CSRF-TOKEN ヘッダ、Rails は X-CSRF-Token$.ajaxSetup() でグローバル設定
  • モダン代替: 標準 fetch API または axios。新規は jQuery より fetch/axios を推奨
  • エラーハンドリングは .fail() でステータスコード分岐、タイムアウトは timeout オプション

基本: $.ajax()

もっとも汎用的な書き方。すべてのオプションを指定可能です。

$.ajax({
  url: '/api/users',
  type: 'GET',                // メソッド (GET/POST/PUT/DELETE)
  dataType: 'json',           // レスポンス形式
  data: { keyword: 'taro' },  // 送信データ
  headers: {
    'Authorization': 'Bearer ' + token,
  },
  timeout: 5000,              // ms
  cache: false,
})
.done(function (data, textStatus, jqXHR) {
  console.log('成功:', data);
})
.fail(function (jqXHR, textStatus, errorThrown) {
  console.error('失敗:', jqXHR.status, errorThrown);
})
.always(function () {
  console.log('完了 (成功失敗問わず)');
});

ショートカット: $.get / $.post / $.getJSON

// GET
$.get('/api/users', { id: 1 }, function (data) {
  console.log(data);
}, 'json');

// POST
$.post('/api/users', { name: 'taro', age: 25 }, function (data) {
  console.log('作成:', data);
});

// JSON 専用 GET (dataType: 'json' 固定)
$.getJSON('/api/users.json', function (data) {
  $.each(data, (i, u) => $('#list').append(`
  • ${u.name}
  • `)); }); // HTML を取得して特定要素にロード $('#main').load('/partials/sidebar.html'); // セレクタ指定で部分ロード $('#main').load('/page.html #content');

    Promise チェーン (.done / .fail / .always / .then)

    jQuery 1.5 から Ajax は jqXHR (Promise) を返します。Promise チェーンで複数リクエストを連結できます:

    // 連続 Ajax
    $.getJSON('/api/user/1')
      .then(function (user) {
        return $.getJSON('/api/posts?userId=' + user.id);
      })
      .then(function (posts) {
        console.log(posts.length + ' 件の投稿');
      })
      .fail(function (xhr) {
        console.error('どこかで失敗:', xhr.status);
      });
    
    // 並列 Ajax ($.when)
    $.when(
      $.getJSON('/api/user/1'),
      $.getJSON('/api/posts')
    ).done(function (userResult, postsResult) {
      // userResult = [data, textStatus, jqXHR]
      console.log(userResult[0], postsResult[0]);
    });

    CSRF トークンの送信

    Laravel / Rails 等は POST / PUT / DELETE に CSRF トークンが必要です:

    // Laravel: meta タグから取得
    // 
    $.ajaxSetup({
      headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
      },
    });
    
    // Rails: meta タグの名前が違う
    $.ajaxSetup({
      headers: {
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
      },
    });
    
    // 以降の $.post / $.ajax すべてに自動付与される
    $.post('/users', { name: 'taro' });

    $.ajaxSetup でグローバルデフォルト

    $.ajaxSetup({
      cache: false,
      timeout: 10000,
      beforeSend: function (xhr) {
        xhr.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('token'));
      },
      statusCode: {
        401: function () {
          location.href = '/login';   // 共通の 401 ハンドリング
        },
        500: function () {
          alert('サーバエラーが発生しました');
        },
      },
    });

    ファイルアップロード (FormData)

    const formData = new FormData();
    formData.append('file', $('#file-input')[0].files[0]);
    formData.append('description', '画像説明');
    
    $.ajax({
      url: '/upload',
      type: 'POST',
      data: formData,
      contentType: false,    // ★ jQuery に Content-Type を生成させない
      processData: false,    // ★ FormData をクエリ化させない
      xhr: function () {
        const xhr = $.ajaxSettings.xhr();
        xhr.upload.onprogress = function (e) {
          if (e.lengthComputable) {
            const pct = Math.round((e.loaded / e.total) * 100);
            $('#progress').text(pct + '%');
          }
        };
        return xhr;
      },
    }).done(function (data) {
      console.log('アップロード完了:', data);
    });

    エラーハンドリング

    $.ajax('/api/users')
    .fail(function (jqXHR, textStatus, errorThrown) {
      switch (jqXHR.status) {
        case 0:
          alert('ネットワーク接続を確認してください');
          break;
        case 401:
          location.href = '/login';
          break;
        case 403:
          alert('権限がありません');
          break;
        case 404:
          alert('リソースが見つかりません');
          break;
        case 422:
          // バリデーションエラー (Laravel)
          const errors = jqXHR.responseJSON.errors;
          Object.entries(errors).forEach(([field, msgs]) => {
            $(`[name="${field}"]`).next('.error').text(msgs[0]);
          });
          break;
        case 500:
          alert('サーバエラー');
          break;
        default:
          console.error(textStatus, errorThrown);
      }
    });

    fetch API への移行

    jQuery を使わない場合の同等コード:

    // GET
    fetch('/api/users?keyword=taro')
      .then(res => {
        if (!res.ok) throw new Error('HTTP ' + res.status);
        return res.json();
      })
      .then(data => console.log(data))
      .catch(err => console.error(err));
    
    // POST (JSON)
    fetch('/api/users', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': csrfToken,
      },
      body: JSON.stringify({ name: 'taro', age: 25 }),
    })
    .then(res => res.json())
    .then(data => console.log(data));
    
    // async / await
    async function fetchUser(id) {
      const res = await fetch(`/api/users/${id}`);
      if (!res.ok) throw new Error('HTTP ' + res.status);
      return await res.json();
    }

    axios との比較

    項目jQuery Ajaxfetch (標準)axios
    サイズ大 (jQuery 30KB+)0 (組込)13KB
    JSON 自動変換○ (dataType: json)× (.json() 必要)
    HTTP エラーfail で捕捉× (4xx/5xx も resolve)○ catch で捕捉
    キャンセルxhr.abort()AbortControllerCancelToken
    インターセプタ$.ajaxSetupなし (要ラップ)あり
    進捗xhr.upload.onprogress限定的onUploadProgress

    FAQ

    Q: 新規プロジェクトで jQuery Ajax を使うべき?
    A: 既存 jQuery 環境ならアリ。新規は fetch / axios を推奨。

    Q: $.ajaxasync: false は使える?
    A: 同期 XHR はブラウザが非推奨化。UI フリーズを起こすので使わない。

    Q: jqXHR と XHR の違い
    A: jqXHR は jQuery が XHR を Promise でラップしたもの。.done() / .fail() 等のメソッドが使える。

    編集
    Post Share
    子ページ
    1. $.ajax()
    2. CSVファイルのダウンロード
    同階層のページ
    1. 導入方法
    2. 文法
    3. HTML/CSS 操作・制御
    4. 要素の取得
    5. 値の取得
    6. 値と要素の追加
    7. 値と要素の削除
    8. 子要素の削除
    9. 要素のコピー
    10. Ajax
    11. 項目をタッチ/クリックしてスライドさせる方法
    12. テキスト/セレクトボックス/ラジオボタン変更時のイベント
    13. パスワードを一時的に表示させる方法
    14. $(document).ready(function() { ...
    15. セレクトボックスにオプションを追加する方法