XMLHttpRequestとjQuery.ajaxの関係を理解する

XMLHttpRequestとjQuery.ajaxは「別物」ではありません

まず重要な点から書きます。
jQueryの`$.ajax()`はXMLHttpRequestの代替ではありません。
内部でXMLHttpRequestを使っています。

つまり関係はこうです。

  • XMLHttpRequest … ブラウザが持つ低レベル通信API
  • jQuery.ajax … それを扱いやすくした高レベルAPI

よく「昔はjQueryでAjax通信していた」と言われますが、
実際には「XMLHttpRequestをjQuery経由で操作していた」が正確です。

この関係を理解すると、jQueryの役割と限界がはっきり見えてきます。

XMLHttpRequestはなぜ扱いにくかったのか

XMLHttpRequest自体は非常にシンプルなAPIです。
しかし、シンプルであることと使いやすいことは別です。

典型的なコードを見てみます。

var xhr = new XMLHttpRequest();
xhr.open("GET", "/api/data", true);

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      console.log(xhr.responseText);
    } else {
      console.error("通信エラー");
    }
  }
};

xhr.send(null);

これだけでも、次の知識が必要になります。

  • readyStateの意味
  • HTTPステータスコード
  • 非同期イベントの理解
  • エラー分岐
  • レスポンス処理

さらに実務ではここに追加されます。

  • POST送信
  • JSONのパース
  • タイムアウト
  • ヘッダ設定
  • 例外処理
  • ブラウザ差異

つまり、単に「データを取りたい」だけでも、通信プロトコルの知識が必要でした。

jQuery.ajaxがやったこと ― 抽象化

jQuery.ajaxはXMLHttpRequestを隠したのではありません。
抽象化しました。

抽象化とは、難しい内部構造を意識せず使えるようにすることです。

同じ処理をjQueryで書くとこうなります。

$.ajax({
  url: "/api/data",
  method: "GET",
  success: function(data){
    console.log(data);
  },
  error: function(){
    console.error("通信エラー");
  }
});

ここで開発者が考えることは次の2つだけです。

  • どこにアクセスするか
  • 成功したら何をするか

readyStateもstatusも見えません。
しかし内部ではきちんと判定されています。

これが「ラッパー」の意味です。
低レベルAPIを包み、意識しなくても使える形にしています。

内部で何が起きているのか

jQuery.ajaxは実行されると、内部で次の流れが動きます。

1. XMLHttpRequestを生成**

ブラウザごとに生成方法を切り替えます(特に旧IE)。

2. オプション解析**

url / method / headers / dataType を整理。

3. イベント登録**

readystatechangeを監視。

4. ステータス判定**

HTTP 200系 → success
それ以外 → error

5. レスポンス変換**

text / json / script / html を自動処理。

6. コールバック実行**

success / error / complete を順番に呼び出す。

つまりjQuery.ajaxは単なる関数ではなく、
XMLHttpRequestの「ライフサイクル管理ツール」です。

具体例:JSON取得の違い

JSON取得の比較を見ると、関係が非常に分かりやすいです。

XMLHttpRequest**

var xhr = new XMLHttpRequest();
xhr.open("GET", "/user.json", true);

xhr.onreadystatechange = function(){
  if(xhr.readyState === 4 && xhr.status === 200){
    var user = JSON.parse(xhr.responseText);
    console.log(user.name);
  }
};

xhr.send();

jQuery.ajax**

$.ajax({
  url: "/user.json",
  dataType: "json",
  success: function(user){
    console.log(user.name);
  }
});

ここで重要なのは、jQueryがJSON.parseを書かせていない点です。
`dataType: "json"`により内部でパースしています。

つまり、

  • XMLHttpRequest → 「通信機能」
  • jQuery.ajax → 「通信+データ処理」

になっています。

なぜ当時jQueryが必須に近かったのか

理由はブラウザ互換性です。

昔のWebは現在とは比較にならないほど不安定でした。

同じXMLHttpRequestでも

  • IEではActiveXObject
  • Firefoxでは標準
  • Safariではヘッダ制限
  • Operaでは挙動差

という状況でした。

つまり開発者は、通信処理を書くたびにブラウザ分岐を書く必要がありました。

if (window.XMLHttpRequest) {
  xhr = new XMLHttpRequest();
} else {
  xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

このようなコードが普通に必要でした。
jQuery.ajaxはこれをすべて内部に隠しました。

その結果、
「どのブラウザでも同じコードが動く」
という、当時としては画期的な環境が生まれました。

注意点:jQuery.ajaxはXHRの制限を超えない

ここは誤解されやすい部分です。

jQuery.ajaxはXMLHttpRequestを便利にするだけです。
XMLHttpRequestの制限は突破しません。

代表例が同一オリジン制約です。

  • 他ドメインへ自由にアクセスできるようになる

→ ならない

この制限はブラウザのセキュリティ仕様です。
jQueryでは回避できません(JSONPを除く)。

つまり、

jQuery.ajax ≠ 通信を自由にするツール
jQuery.ajax = 通信コードを簡単にするツール

です。

fetchとの関係

現在のfetch APIは、XMLHttpRequestの後継に近い存在です。

違いは次の通りです。

項目 XMLHttpRequest fetch
同期処理 可能(現在は非推奨) 不可
コールバック イベント型 Promise型
レスポンス処理 手動 オブジェクト化
可読性 低い 高い

そして重要なのは、fetchはjQuery.ajaxの思想を標準化したAPIという点です。

  • シンプルな記述
  • 非同期の整理
  • データ処理の明確化

これらはjQueryが先に解決した問題でした。

まとめ

XMLHttpRequestとjQuery.ajaxは競合関係ではありません。
上下関係です。

XMLHttpRequestが基盤で、jQuery.ajaxが操作インターフェースです。

当時の開発者はXMLHttpRequestを直接扱うのではなく、
jQueryという「通訳」を通して通信していました。

そして現在は、ブラウザ自身がその通訳の役割を持ち始めています。
jQueryの役割は消えたのではなく、ブラウザに取り込まれたと言えます。