最終更新日:
公開日:
レシピ
Ajax
XMLHttpRequestによるファイルの読み込み状況を取得する
XMLHttpRequestによるデータ読み込みの途中経過を調べる方法について解説します。
この記事のポイント
- サーバーから読み込んでいる間はProgressEventオブジェクトのloadedプロパティから読み込んだバイト数を取得する
- ファイルサイズはtotalプロパティを参照する
- ファイルサイズを取得できるかどうかはlengthComputableプロパティから確認する
Ajaxでサーバーから読み込むファイルの途中経過を取得
XMLHttpRequestオブジェクトによるAjaxを使ってサーバーから特定のファイルを読み込むとき、現在どれだけ読み込んだか調べるときはProgressEventオブジェクトのloadedプロパティから取得することができます。
ProgressEventオブジェクトはXMLHttpRequestオブジェクトによるサーバーとの通信において、レスポンスデータを受け取っているときに発生します。
このオブジェクトのプロパティはイベントprogressを検出したときに引数として受け取って参照します。
JavaScript コード例
xhr.open('get', './test.mov', true);
xhr.responseType = 'blob';
xhr.send();
xhr.addEventListener('progress',(e) => {
// 読み込んだバイト数を表示
console.log(e.loaded);
});
イベントprogressはレスポンスデータを受け取っている間は定期的に発生するため、読み込むファイルのサイズ(容量)が大きいほど繰り返し発生します。
例えば上記のコードで約65.7MBのファイルをサーバーから読み込むと、以下のように現時点で読み込んだバイト数を出力します。
コンソールの出力例
524288
9764864
21168128
30081024
40566784
65665095
ProgressEventオブジェクトには読み込むファイルのサイズが数値で入ったtotalプロパティが用意されています。
totalプロパティとloadedプロパティを組み合わせると、現在全体の何%を読み込んだかを調べることができます。
ただし、サーバーによってファイルのサイズを取得できないことがあります。
totalプロパティからファイルサイズを取得できるかどうかはlengthComputableプロパティで確認することができるため、取得できるときとできないときで処理を分岐させることが可能です。
以下の例では、サーバーから「test.mov」というファイルを取得して、読み込みが完了したらid属性「file_area」のdiv要素に動画を表示します。
ファイルの読み込み状況はid属性「text_loading」のp要素に表示します。
HTML コード例
<article>
<h1>JavaScriptレシピ</h1>
<div id="file_area"></div>
<p id="text_loading"></p>
</article>
JavaScript コード例
// 読み込むファイルのURLを指定して通信開始
xhr.open('get', './test.mov');
xhr.responseType = 'blob';
xhr.send();
// レスポンスデータを受け取っている間は定期的に発生するイベント
xhr.addEventListener('progress', (e) => {
// p要素に進捗状況を表示
if( e.lengthComputable ) {
text_loading.textContent = Math.floor((e.loaded / e.total) * 100) + "%";
} else {
text_loading.textContent = "読み込み中";
}
});
xhr.onreadystatechange = function() {
// 通信が正常に完了したか確認する
if( xhr.readyState === 4 && xhr.status === 200) {
// p要素に読み込み完了を表示
text_loading.textContent = "読み込み完了";
// 読み込んだ動画ファイルを表示
const file_area = document.getElementById("file_area");
const video_element = document.createElement('video');
video_element.src = URL.createObjectURL(this.response);
video_element.controls = true;
file_area.appendChild(video_element);
}
};
lengthComputableプロパティはファイルサイズを取得できる場合はtrue、取得できない場合はfalseが入ります。
そこで、上記のようにif文を使ってファイルサイズを取得できたときのみ「読み込んだバイト数 / ファイルサイズ」という計算をして現在の進捗を表示します。
ファイルサイズを取得できなかったときは読み込んでいる間は「読み込み中」と表示して、読み込み完了したときに「読み込み完了」と表示します。
こちらの記事は役に立ちましたか?
コメントありがとうございます!
運営の参考にさせていただきます。
ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。