如何使用JavaScript(客户端)上传文件夹的内容? Chrome以外的浏览器尚未采用FileSystem API;我只得到一个带有文件夹名称的文件项。
应该可以,因为Google云端硬盘允许删除文件夹,所有内容(文件夹和文件)都会自动上传。
答案 0 :(得分:5)
您实际上可以在所有最新版本的Chrome,Firefox和Microsoft Edge中上传目录。有许多工作示例可供查看。
这是我之前在项目中使用过的一个很好的工作示例
Quarklemotion Html5FileSelector
此外,Dropzone JS也支持目录上传,并且可以在Chrome,FF和Edge中使用。我刚刚在自己的项目中过渡到使用它。
这些解决方案递归地读取目录条目并列出所有文件,包括它们的相对路径。如果要在上载时重建文件夹结构,则必须使用相对路径和相应的算法来实现它。
答案 1 :(得分:4)
我已经使用webkit作了一个完整的例子。
纯Javascript,HTML和PHP,无需任何其他库。
可以免费下载或克隆我的仓库。
答案 2 :(得分:2)
Chrome和Firefox似乎支持部分文件系统API,但并未正式支持。
这允许您删除文件夹并读取所有内容,这是我在应用程序上使用的代码。
function add Files(e){
e.stopPropagation();
e.preventDefault();
// if directory support is available
if(e.dataTransfer && e.dataTransfer.items)
{
var items = e.dataTransfer.items;
for (var i=0; i<items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
addDirectory(item);
}
}
return;
}
// Fallback
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
{
alert('File type not accepted');
return;
}
processFile(files);
}
function addDirectory(item) {
var _this = this;
if (item.isDirectory) {
var directoryReader = item.createReader();
directoryReader.readEntries(function(entries) {
entries.forEach(function(entry) {
_this.addDirectory(entry);
});
});
} else {
item.file(function(file){
processFile([file],0);
});
}
},
答案 3 :(得分:0)
不幸的是,目前只有基于webkit的浏览器支持文件系统API。
如果您尝试使用firefox或Internet Explorer在Google云端硬盘中删除某个文件夹,则会收到一条错误消息,指出它不受支持。
答案 4 :(得分:0)
如果可以使用非标准属性,则可以使用webkitdirectory
属性:
let picker = document.getElementById('picker');
picker.addEventListener('change', e => {
for (let file of Array.from(e.target.files)) {
alert(`File located at ${file.webkitRelativePath}`);
};
});
答案 5 :(得分:0)
在JS端,我使用以下方法(来自StackoverFlow上的老师-https://stackoverflow.com/a/47935286/11544097)来循环和归档所有文件,文件夹内容和子文件夹:
function makedir(entries){ const systems = entry.map(entry => traverse(entry,{})); 返回Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for(let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
};
function checkFile(obj){
return obj instanceof File;
};
function exactFile(system_trees, relativePath, files){
for (var i = 0; i < system_trees.length; i++){
for (var property in system_trees[i]) {
if (system_trees[i].hasOwnProperty(property)) {
if (checkFile(system_trees[i][property])){
system_trees[i][property]["relativePath"] = relativePath;
files.push(system_trees[i][property]);
} else {
files.concat(exactFile([system_trees[i][property]], (typeof relativePath !== 'undefined' && relativePath !== '' ? (relativePath + '/') : '') + property, files));
}
}
}
}
return files;
};
function readDropped(dT,_data) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries).then(function(system_trees){
var files = exactFile(system_trees, "", []);
c(_data, files);
}).catch(function(){
var files = dT.files;
c(_data, files);
});
} else {
var files = dT.files;
c(_data, files);
}
};
您还需要一个上传库或自己编写,以通过ajax上传发送到文件到服务器。在上面的代码示例中,我使用了Formstone上传库(https://formstone.it/components/upload/)
在服务器端:您需要处理从JS端发送的表单数据,大多数情况下,您需要使用文件对象中包含的相对路径信息逐个文件地处理文件。
还有一点要注意,只需在文件上传输入处设置“ multiple”属性,就不需要“ webkitdirectory”或“ directory”。它们导致用户无法选择文件(仅允许文件夹)
结果将使您的上传系统支持所有文件夹,文件将保持其结构,如Google Drive:)。
我已经编写了一种工具(https://freetoolonline.com/zip-file.html),该工具基于上面已经解释过的理想支持文件夹上传。