input type="file" タグを使用すると、ブラウザ上でファイルをアップロードすることができます。
通常は JavaScript で change
イベントを定義しておけばファイルをアップロードし直す度に特定の処理を行うよう定義できます。
しかし、同名ファイルをアップロードすると、この change
イベントが発火しない問題にハマったので原因と対策を備忘録としてメモします。
fakepath について
input type="file" の value プロパティはファイル自体ではなく、そのファイルのパスを保持します。
しかし、この value プロパティはセキュリティ上の理由で、選択されたファイルのフルパスを返すことはありません。
実際のファイルの所在を表示すると、ディレクトリ構造を推測されたり、攻撃の脆弱性に繋がったりしてしまいます。
代わりに、ファイル名の前に "C:\fakepath" という仮のパスが付与されます。
同名ファイルの再アップロードの挙動
この fakepath が原因で、同名のファイルをアップロードした場合、input タグの value が変わらないのです。
change イベントは value の変化を検知するイベントなので、value が変わらないということは、再度同じファイルを選択しても change イベントは発火しないのです。
対処法について
ファイルを選択するたびに、input タグの value をリセットするのが手っ取り早いです。
document.getElementById('inputFile').addEventListener('change', function() {
// 何らかの処理
this.value = '';
});
これにより、ファイルが選択される度に change イベントが確実に発火します。
クリックイベントの利用
input タグをクリックするたびに value をリセットする方法もあります。
これにより、ファイル選択の前に value がリセットされるため、同名ファイルを選択しても change イベントが発火します。
document.getElementById('fileInput').addEventListener('click', function() {
this.value = '';
});
この方法は、ファイル選択のダイアログをキャンセルしても value がリセットされる点に注意が必要です。
コメント