リクエストの中止について

javascript

リクエストの中止について

要領の大きいファイルを通信中に、処理を中止したい時があります。
通信処理を途中で中止する方法を試してみます。

通信処理中のHTTPリエクトを中止するには、abort()メソッドを呼び出して中止します。

abort()メソッドを呼び出すと、abortイベントが発生し、通信処理を停止します。

通信処理中のリクエストを中止する方法として、下記のようなHTMLを用意しました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<form id="testform" enctype="multipart/form-data">
	<div>
		<input type="file" name="file1" id="file1">
	</div>
	
	<div>
		<label for="progress">進捗</label>
		<div id="percent"></div>
		<progress id="progress" value="0" max="100"></progress>
	</div>
	
	<div>
		<input type="button" id="sample_file_upload" value="ファイルアップロードのテスト">
	</div>

	<div>
		<input type="button" id="stop_file_upload" value="ファイルアップロードの中止">
	</div>

</form>

<div>通信時の処理内容</div>
<div id="ajax_result"></div>

<script type="text/javascript">

// ファイルアップロード中止ボタンのDOMを取得
let element_stop_file_upload = document.getElementById('stop_file_upload');
// ファイルアップロード中止ボタンを非表示にする
element_stop_file_upload.style.display = 'none';


// ファイルアップロードボタンのDOMを取得
let element_sample_file_upload = document.getElementById('sample_file_upload');

element_sample_file_upload.addEventListener('click',  SendXMLHttpRequest, false);

// ボタン押下時の処理
function SendXMLHttpRequest()
{

	// 通信処理を画面に出力する為、操作用DOMの取得
	let result = document.getElementById("ajax_result");
	result.innerHTML += 'ファイルアップロードのテスト start' + '<br />';
	result.innerHTML += '通信処理の開始' + '<br />';

	// フォーム内容の取得
	let testform_data = document.getElementById("testform");

	// 送信用データ
	let form_data = new FormData(testform_data);

	// 通信用XMLHttpRequestを生成
	let req = new XMLHttpRequest();

	// POST形式でサーバ側の「response.php」へデータ通信を行う
	req.open("POST", "response.php");

	// ファイル通信時の進捗確認用にプログレスバーを更新する
	req.upload.addEventListener("progress", function(e) {

		if (e.lengthComputable) {

			// ファイルアップロード中止ボタンを表示する
			// document.getElementById('stop_file_upload').style.display = 'block';
			element_stop_file_upload.style.display = 'block';

			let progress_value = Math.round(e.loaded / e.total * 100);

			// 進捗%表示用に値を更新する
			document.getElementById('percent').innerHTML = progress_value + "%";
			
			// プログレスバーの値にファイル転送値を代入する
			document.getElementById('progress').value = progress_value;

			// 進捗率が100%になったら終了の処理をする
			if (progress_value == 100) {
				// 通信が完了したらレスポンスをコンソールに出力する
				req.addEventListener('readystatechange', () => {
					// ここでレスポンス結果を制御する
					console.log("レスポンス結果");
				});

				result.innerHTML += '通信処理の終了' + '<br />';
				result.innerHTML += 'レファイルアップロードのテスト end' + '<br />';
			}

		}
	});

	// ファイルが選択されたときに処理を実行するようイベントリスナーに登録
	input_file = document.getElementById("file1");
	input_file.addEventListener('change', function(e) {
		form_data.append('file1', e.target.files[0]);
	});

	// ファイルアップロードの中止ボタン
	element_stop_file_upload.addEventListener('click', function(e) {
		req.abort();
	});
	
	// ファイル送信
	req.send(form_data);

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

上記の画面にアクセスし、サイズの大きいファイルを転送中に、
「アップロード中止」のボタンを押すと、転送が中止されます。

ポイントとなる箇所は以下の箇所です。

	// ファイルアップロードの中止ボタン
	element_stop_file_upload.addEventListener('click', function(e) {
		req.abort();
	});

通信用XMLHttpRequestを生成した後、XMLHttpRequestオブジェクトに対してabortメソッドを実行しています。

また、一度停止した通信処理は、またファイル送信処理を実行すると
最初からファイルが転送されます。

レジューム機能を伴ったアップロード方法にするには、転送するファイルに
一意なIDを付与し、そのIDをもとにサーバに転送済のファイル要領を確認し、
未転送バイトからのアップロードをする。といった一連の処理が必要になります。
(今回の投稿ではその方法は試しませんが、別な投稿でまとめるかもしれません)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です