JavaScriptのXMLHttpRequestを使ったデータ通信をキャンセルする方法

JavaScriptのXMLHttpRequestを使ったデータ通信をキャンセルする

JavaScriptでデータの送信・受信を行う場合、fetch()メソッドを使うのが一般的ですが、昔から存在する機能でXMLHttpRequestがあります。

XMLHttpRequestはfetch()メソッドよりも冗長な書き方をしなければいけませんが、画像読み込み時にプログレスバーを出すことができる点でfetch()メソッドよりも優れています。

補足

fetch()メソッドでもプログレスバーを出すことができる様ですが、ハック的な実装になります。

メソッド

メソッド意味返り値
new XMLHttprequest()インスタンスを生成するXMLHttpRequest
opne(メソッド, url)リクエストを読み込むなし
send()リクエストを送信するなし
abort()通信を中断するなし
XMLHttpRequestAPIの仕様

サンプルコード

100%完了する画像読み込み処理

データを普通に読み込むだけなら、下記の様なコードで十分でしょう。

XMLHttpRequestは基本的にloadイベントを監視して処理後の動作を実装します。

Output
読み込まれた画像の中身
Pug
table.table
			tbody
				tr
					th 読み込まれた画像の中身
					td#targetText
JavaScript
const targetText = document.getElementById("targetText");

// XHRを作成
  const req = new XMLHttpRequest();

// データの種類を設定
  req.responseType = 'blob';
	
  // 読み込み完了時のイベント
  req.addEventListener('load', (event) => {
    // レスポンスを受け取る
    const data = event.target.response;
    // 画像データに変換
    const source = URL.createObjectURL(data);

    // 画像を作成
    const image = new Image();
    image.src = source;
    // テキストを出力
    targetText.appendChild(image);
  });

  // ファイルを指定
  req.open('GET', 'https://idea-hack.com/wp-content/uploads/2020/03/76751b0e74e8b8890bb32967852e507a-1.jpg');
  // 読み込み開始
  req.send();

50%の確率で失敗する処理

しかし、もし通信を途中でキャンセルすることができる処理を追加したい場合はどうでしょうか?この場合はabort()メソッドを使って処理を追加する必要があります。

サンプルコードは下記の通りです。今回は、処理が失敗する様に作っています。これは、サンプルコードのJSの末尾でabort()を実行しているためです。

Output
読み込まれた画像の中身
Pug
table.table
			tbody
				tr
					th 読み込まれた画像の中身
					td.text-center
						div.progress
							div.progress-bar
						div#targetText2
SCSS
.progress {
  position: relative;
  width: 600px;
  height: 20px;
  border-radius: 10px;
  background: gray;
  overflow: hidden;
  display: block;
  margin: 20px auto;
	.progress-bar {
  position: absolute;
  background: #40739e;
  content: '';
  height: 20px;
  display: block;
	}
}
JavaScript
const targetText2 = document.getElementById("targetText2");

// XHRを作成
  const req2 = new XMLHttpRequest();

	// データの種類を設定
  req2.responseType = 'blob';
	
  req2.addEventListener('abort', (event) => {
    // 画面に表示
    targetText2.textContent = '読み込みに失敗しました';
  });
	
	// 読み込みに失敗したときのイベント
	req2.addEventListener('progress', (event) => {
    // 読み込みの割合を算出(0〜1)
    const rate = event.loaded / event.total;

    // プログレスバーの幅を変更する
    const element = document.querySelector('.progress-bar');
    element.style.width = `${rate * 100}%`;
  });

  // 読み込み完了時のイベント
  req2.addEventListener('load', (event) => {
    // レスポンスを受け取る
    const data2 = event.target.response;
    // 画像データに変換
    const source2= URL.createObjectURL(data2);

    // 画像を作成
    const image2 = new Image();
    image2.src = source2;
    // テキストを出力
    targetText2.appendChild(image2);
  });


  // ファイルを指定
  req2.open('GET', 'https://idea-hack.com/wp-content/uploads/2020/03/76751b0e74e8b8890bb32967852e507a-1.jpg');

  // 読み込み開始
  req2.send();
	
	//通信を停止させ、処理を失敗させる
	req2.abort();
インストラクター