選択したファイルをAJAX=経由でAPIエンドポイントに送信する単純なHTMLフォームがあります。
次の手順を実行した場合:
Chromeは2番目のリクエストをnet::ERR_UPLOAD_FILE_CHANGED
のエラーで失敗します。最初のアップロードの前にファイルを変更した場合、ファイルは問題なくアップロードされることに注意してください。エラーは、最初のアップロードが正常に完了した後でファイルを変更したときに、2番目のアップロードでのみ発生します。これをCSVファイルでテストし、テキストエディターで変更しています。
そのエラーを分離する方法はないようです。
これを回避する方法はありますか?
そうでない場合は、この特定のエラーをキャッチして、ユーザーに意味のあるメッセージを表示することができます。 Fetchがpromiseで返すエラーには、これに関する特定の情報はありません。 ERR_UPLOAD_FILE_CHANGED
が表示される唯一の場所は、ブラウザの開発コンソール内です。
変更されたファイルを再アップロードする可能性があり、UIフローでうまく機能したので、約1年前(2019年初頭)に問題がなかったと確信しています。ここで、ユーザーにファイルを再度選択させる必要があります。つまり、これは最近のchromeの更新で導入されたものです。
以下は、コードの簡略化されたスニペットです。
<html>
<head>
<script type='text/javascript'>
document.addEventListener("DOMContentLoaded", function(){
const button = document.querySelector('#btnSubmit');
button.addEventListener('click', () => {
const form = new FormData(document.querySelector('#theForm'));
const url = '/my-api'
const request = new Request(url, {
method: 'POST',
body: form
});
fetch(request).then(function() {
console.log("ok");
}).catch(function(err) {
console.log(err);
});
});
});
</script>
</head>
<body>
<form enctype="multipart/form-data" action="" method="post" id='theForm'>
<input type="file" name="csvfile" id="csvfile" value="" /></td>
<input type="button" name="uploadCSV" value="Upload" id='btnSubmit'/>
</form>
</body>
</html>
いいえ、ユーザーがファイルを既に別のファイルに変更している場合、ユーザーが明示的なユーザーアクションなしにこのファイルにアクセスすることはできません(すべきではありません)。
ユーザーがアップロードしたときに、ファイルをメモリに保存できます。
document.getElementById('fileInput').addEventListener('change', function() {
saveFileConentInMemory(this.files[0].arrayBuffer());
});
そして、ユーザーが「送信」ボタンを押すと、メモリからこのコンテンツを取得して送信します
button.addEventListener('click', () => {
const file = getFileContentFromMemeory();
send(file);
})
はい、確実に最新バージョンのファイルを送信することはできませんが、アップロードされたコンテンツを送信することを確認する必要があります。
また、メモリの消費とファイルの読み取りの非同期APIに注意する必要があります(メモリに書き込んでも、変更されたコンテンツに関するこのエラーが発生する可能性があります)
アップロードボタンのクリックの間にfile.lastModifiedを確認し、異なる場合はフォームの値をリセットします。
https://developer.mozilla.org/en-US/docs/Web/API/File/lastModified
より良い解決策は、ファイルをArrayBufferに読み込んでアップロードすることです。