Ajaxは、JavaScriptでサーバー側と非同期通信を行うための技術です。非同期処理や同期処理については前回の記事で解説していますので、イメージが掴めていない方はまず前回の記事を読んで非同期処理について理解を深めてください。

/javascript/asynchronous-processing

筆者はシステム開発とWEB制作の両方に関わっていますが、WEB制作の場面でAjax通信を使用するケースはほとんどありません。非同期コールバック(setTimeout関数など)を用いてDOM操作を行うことはありますが、サーバーと通信して、取得したデータを加工する処理は基本的には開発で使用します。

jQueryなどのフレームワークを含めると、JavaScriptでAjax通信を行うための手段は複数用意されています。これから何回かに分けて、私が実際に使用しているメソッド(fetch, XMLHttpRequest, $.ajax)について解説したいと思います。

この章ではXMLHttpRequestについて解説します。

XMLHttpRequest

XMLHttpRequestオブジェクトはWEB サイトとサーバーの間でデータを交換するために使用されるオブジェクトです。XMLHttpRequestを使用することでページ全体を更新する必要なくデータを受信することができます。

現在はfetchメソッドを使用してPromiseの記法で処理を実装するケースが多いですが、現場によってはまだまだXMLHttpRequestが使用されているケースもあります。開発に関わる上で記法と処理については理解しておく必要がありそうです。

リスエストの送信

const button = ボタン要素;
const url = URL;

// ボタンがクリックされたら指定URLのデータを取得する
button.addEventListener('click', function() {
  // XMLHttpRequestインスタンスの作成
  const req = new XMLHttpRequest();
  req.onreadystatechange(function() {
   if(req.readyState === 4 && req.status === 200) {
    // 成功時の処理
       console.log(req.responseText);
     } else {1
    // 例外処理
   }
 });
  // HTTPメソッドとアクセス先を指定
  req.open('GET', url);
  // リクエストを送信する
  req.send();
});

【処理順に解説】

new XMLHttpRequestでオブジェクトを作成する
onreadystatechangeで読み込み時の動作を指定(読み込み途中、読み込み完了、失敗)
処理状況が変化するたびにonreadystatechangeイベントが発生し、プログラムによってその変化に応じた処理を行うことができます。下記で説明をしていますが、現在の処理状況を取得したい場合は、readyStateで取得できます。
open()で送信時のメソッド(‘GET’ or ‘POST’)、送信先URL、通信手段を指定(非同期 or 同期)を指定
通信手段の指定を省略した場合は非同期処理になります
send()でリクエストを送信

処理状況の把握

req.readyState 

上記の記述により、読み込み状態を管理しています。readyStateプロパティの値が4のとき、読み込み完了を示します。

readyStateは0 ~ 4の数字が割り当てられており、それぞれの意味は下記です。

処理状況別のreadyState

・readyState = 0(UNSENT) 初期状態
・readyState = 1(OPENED)  openメソッド実行
・readyState = 2(HEADERS_RECEIVED) レスポンスヘッダー受信
・readyState = 3(LOADING)  データ受信中
・readyState = 4(DONE) 処理完了

処理状況に応じたイベント

・onloadstart : リクエスト開始時
・onprogress : リクエストが完了するまで周期的に実行される。
・onabort : abort()によりリクエストが中断された時
・onerror : リクエストでエラーが発生した時
・onload : リクエストが完了した時
・ontimeout : リクエストがタイムアウトした時

処理状況に応じたイベントを使用したサンプル

const button = ボタン要素;
const url = URL;

button.addEventListener('click', function() {
 const req = new XMLHttpRequest();
 req.onloadstart = function() {
  // 処理
 }
 req.onprogress = function() {
  // 処理
 }
 req.onload = function() {
  // 処理
 }
 req.onabort = function() {
  // 処理
 }
 req.onerror = function() {
  // 処理
 }
 req.ontimeout = function() {
  // 処理
 }
})

各フェーズの処理状態を元に処理を書くこともできますが、コードが肥大化して少し可読性は下がります。

しかし、処理状況に応じたイベント処理はDOMにローディングを表示させる際などに使用するケースがあるので、使い方を知っておくことは有益です。

ステータスコード

req.status

加えてstatusコードも条件に加えます。成功時のステータスコードが200なので、処理が成功している場合はresponseTextからレスポンスの内容を受け取ることができます。

レスポンスデータの受信・加工

WEB開発でサーバーにAjaxリクエストを送信した際、ネット上にあるサンプルコードのようにシンプルな文字列を返す例はほとんどありません。大抵はまとまったデータ(ユーザー情報、商品情報など)をJSONデータとして返します。

if(status === 0 || (status >= 200 && status < 400)) {
  console.log(req.responseText);
} else {
  // 例外処理
}

XMLHttpRequestで受け取ったデータ(responseText)をそのまま表示させる場合は、undefinedになります。そのためレスポンスデータがJSONの場合はJSON.parse()を実行する必要があります。

if(status === 0 || (status >= 200 && status < 400)) {
  const data = JSON.parse(req.responseText);
  console.log(data);  // 取得したデータは表示される
} else {
  // 例外処理
}

もしくは、responseType を指定してjson, text, blobなどのデータ形式を指定することができます。

const button = ボタン要素;
const url = URL;
button.addEventListener('click', function() {
  const req = new XMLHttpRequest();
  // レスポンスの形式を指定
  req.responseType = 'json';
  // req.responseType = 'text';
  // req.responseType = 'blob';
  req.open('GET', url);
  // 処理状態変化の検知
  req.onreadystatechange(function() {
  // 成功時の処理
    if(req.readyState === XMLHttpRequest.DONE) {
      const status = req.status;
      if(status === 0 || (status >= 200 && status < 400)) {
        console.log(req.response);
      } else {
        // 例外処理
      }
     }
  });
  req.send();
})

responseTypeを指定した場合は、JSON.parse()などの変換処理を行う必要はなく、データを表示させることができます。その場合responseTextではなくresponseで取得しますので、記述を間違わないようにする必要があります。

参考 : https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

カテゴリー: JavaScript