【JavaScript】FireFoxでプログレスバーが動作しない【XMLHttpRequest】

以下の記事、<progress> タグを使用したプログレスバー実装途中に Mozilla FireFox ブラウザでのみ動作しない現象が発生したときの備忘録。

現象

XMLHttpRequest を使用してファイルアップロードの進行状況を <progress> タグ(プログレスバー)で表示する画面を実装し、各ブラウザで確認していたところ FireFox でのみプログレスバーが動作しなかった。確認していたブラウザは以下。

Google Chrome => OK
Microsof Edge => OK
Mozilla FireFox => NG

参考コード

JS
		<script type="text/javascript">
				const bar = document.getElementById("progress");
				const xhr = new XMLHttpRequest();
				const xhr_u = xhr.upload;

				//////////////////// メイン処理 ////////////////////
				xhr.open('post', './upload.php'); //post先ファイルを指定
				fd.append('inUploadForm', inFile.files[0]); // form へセット 
				xhr.send(fd); // データ送信
				//////////////////// メイン処理 ////////////////////

				// アップロード中(何度も発火)
				xhr_u.onprogress = function ( event ) {
					var progVal = parseInt(event.loaded/event.total*10000)/100 ;
					bar.value = progVal;
				}
		</script>

HTML
		<progress id="progress" max="100" value="0"></progress>

割愛したサンプルコードなので動作しませんが大まかな要素だけ載せています。xhr.send でリクエスト送信。アップロード中に複数回発生する progress イベント時にファイルアップロード量を計算、bar.value へ値を入れプログレスバーの更新を行います。

調査

最初は <progress> タグのみが効いていないのかと思いましたが console.log で確認すると xhr.progress イベント自体が発生していない模様。しかしファイルはアップロードされており xhr.send は動作していた。console やサーバー側のエラーログには何も表示されず Firefox 以外のブラウザは動作する。試行錯誤してみたがこれといった手がかりは掴めず。

解決

XMLHttpRequest 側に原因がありそうということで同じような事例がないか検索したらでてきた。
[参考]
https://groups.google.com/g/mozilla.dev.platform/c/ltkN3WOCeDo?pli=1

xhr.open() を呼び出す前に xhr.upload.progress イベントリスナー( ハンドラ:onprogress)の定義が必要…ということらしい。何だそれは。とりあえずそのように順序を入れ替えてテストしてみる。

const bar = document.getElementById("progress");
const xhr = new XMLHttpRequest();
const xhr_u = xhr.upload;

//////////////////// メイン処理 ////////////////////
xhr.open('post', './upload.php'); //post先ファイルを指定
fd.append('inUploadForm', inFile.files[0]); // form へセット 
xhr.send(fd); // データ送信
//////////////////// メイン処理 ////////////////////

// アップロード中(何度も発火)
xhr_u.onprogress = function ( event ) {
	var progVal = parseInt(event.loaded/event.total*10000)/100 ;
	bar.value = progVal;
}

====================== ↓↓↓ ======================

const bar = document.getElementById("progress");
const xhr = new XMLHttpRequest();
const xhr_u = xhr.upload;

// アップロード中(何度も発火)
xhr_u.onprogress = function ( event ) {
	var progVal = parseInt(event.loaded/event.total*10000)/100 ;
	bar.value = progVal;
}

//////////////////// メイン処理 ////////////////////
xhr.open('post', './upload.php'); //post先ファイルを指定
fd.append('inUploadForm', inFile.files[0]); // form へセット 
xhr.send(fd); // データ送信
//////////////////// メイン処理 ////////////////////

入れ替え後に FireFox でもイベントが発生しプログレスバーが正常に動く事を確認できた。

最後に

先人の知恵って偉大。

コメント