HTML Files指定後上傳前,被使用者編輯儲存後引發咬檔錯誤
最近處理一則檔案上傳的需求,發現了一個問題,就是當使用者針對HTML的input type="file"
進行指定檔案後,然後又把檔案開啟來編輯與儲存,然後再去點選上傳按鈕來進行檔案上傳(或其他關於檔案的後續操作),這時候Chrome瀏覽器會給你一組神秘的報錯,且這個錯誤細節不好攔截。
經過千辛萬苦後,終於找到翻出這個錯誤的關鍵字:
DOMException: The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.
DOM例外情況:由於在獲取文件引用後發生的權限問題,通常導致無法讀取請求的文件。
白話的說法,就是:使用者把檔案變更了,我的讀取權限被搶走了。
針對瀏覽器對於讀取權限被搶走,進行錯誤攔截
總要跟使用者明白的說明是怎樣的錯誤吧,不然又要被無端怪罪豈不冤枉?過程需要透過Javascript的File API之FileReader
物件。但這個物件只能用非同步(asynchronously)方式讀取儲存在用戶端的檔案,所以如果要偵測到瀏覽器讀取檔案的權限被搶走,就顯示警告並停止,又得繞路把非同步改成同步,只能說是非常的脫褲子放屁。
以下是解法:
function CheckFileState() {
return new Promise((resolve, reject) => {
let oFile = 修改你要偵測的Selector;
if (!oFile) {
reject("上傳檔案前請先指定檔案。");
}
let oReader = new FileReader();
oReader.onload = function () {
resolve();
};
oReader.onerror = function (e) {
//如果要上面文章中那串錯誤的關鍵字,可以把`e.target.result`拿出來看
reject("偵測到檔案在指定後被修改並儲存,請重新指定。");
};
oReader.readAsArrayBuffer(oFile);
});
}
透過Promise的寫法後,就可以放心開始使用了。
CheckFileState()
.then(() => {
return UploadFiles();
})
.then((oData) => {
console.log(oData);
})
.catch(function (cMessage) {
console.log(cMessage);
//這邊可以順便寫一下把檔案或表單reset的程式碼
});
感想
瀏覽器彈出一下官方標準錯誤,提示給使用者看是會死嗎?