I am working on a drag-and-drop upload feature. Through the drop event, I use e.dataTransfer.items to retrieve the handles for all files and folders, then call the items[n].webkitGetAsEntry() method to get the FileEntry object. Finally, I attempt to use the FileEntry.file((file) => {}) method to retrieve the file object from the callback:
function traverseFileTree(item, path = "") {
// The item here is the return value of webkitGetAsEntry().
const isRecursive = document.getElementById("recursiveOption").checked;
if (item.isFile) {
item.file(
(file) => {
console.log("file", file);
if (file.name.toLowerCase().endsWith(".md")) {
file.fullPath = path + file.name;
files.push(file);
updateFileList();
}
},
(error) => {
console.error(error);
showPopup(`Failed to read file ${item.name}: ${error.message}`);
}
);
} else if (item.isDirectory) {
if (isRecursive || path === "") {
let dirReader = item.createReader();
dirReader.readEntries(
(entries) => {
for (let i = 0; i < entries.length; i++) {
traverseFileTree(entries[i], path + item.name + "/");
}
},
(error) => {
console.error("Failed to read directory:", error);
showPopup(`Failed to read directory ${item.name}: ${error.message}`);
}
);
}
}
}
However, something strange happens: when I open the HTML file directly in the browser (using the file protocol), the .file() method throws an EncodingError: file:
EncodingError: A URI supplied to the API was malformed, or the resulting Data URL has exceeded the URL length limitations for Data URLs.
But, when I serve the same HTML file through a local server (e.g., using Live Server over HTTP), the .file() method works as expected and I can successfully retrieve the file object. http:
I've searched various resources and consulted GPT but couldn't find a definitive answer. I suspect the issue may be related to browser security policies or relative path restrictions. Has anyone encountered this problem or knows what might be causing it?
I wish: Understand the specific cause of this issue. How should I solve similar problems on my own in the future?
Thank you!
The file://
protocol is severely limited in most browsers, Chrome especially. This is due to security concerns, though I could not find documentation on this specific problem (the error is also quite obtuse).
The exact limitations depend on the API used, so try using a different one. For example, instead of dataTransferItem.webkitGetAsEntry()
try dataTransferItem.getAsFile()
, which gives you access to the file name (and size) even on file://
.
For drag-and-dropping directories on Chrome in file://
protocol, the only working alternative I found is the experimental dataTransferItem.getAsFileSystemHandle()
. It gives you a richer set of options, including permissions.