我的工作是制作一个HTML输入,用户可以选择上传"多事物">一次,所有都被接受,";多事物">可以是带有视频的图像,也可以是带有文件夹的图像。或者任何东西(字面上(。
问题是,如何我一直在想一种方法,我已经读过stackoverflow上的其他问题,我读过问我类似问题的人的问题,然后人们回复他使用JSzip。但是我的答案很复杂,并不是直接回答我的问题,他们展示了如何在前端压缩文件,以便下载压缩文件。我不想那样。我的目标是在前端压缩文件,只需点击上传按钮,在服务器上我就会有一个可以提取和播放的zip文件。
这就是我对如何以及应该如何做的思考。
就在我写完这个问题之前,这里有一个例子,一个用户点击了浏览器上的文件输入,出现了一个窗口,要求他选择要上传的内容单击我查看图片用户现在选择了以下内容:
-── folder1
│ ├── myVideo1.mp4
│ └── myVideo2.mp4
├── folder2
│ ├── innerFolder
│ │ └── anything.gif
│ └── something.png
├── myImage1.jpeg
├── myImage2.jpeg
└── myImage3.jpeg
我需要与上面完全相同的结构,这就是为什么我认为我应该压缩它们(我相信我应该,不是100%确定(,因为我也需要文件夹。
用户没有压缩任何内容,只是选择了他想要的文件和文件夹,他点击上传按钮,浏览器压缩/tarballed/。。。或者任何你想要的术语,并将zip/(或任何它的(文件张贴到服务器。
我现在可以从这个文件中提取所有内容,并以我想要的方式在服务器中保护它们。
问题的结尾
我看过
<input type="file" webkitdirectory mozdirectory />
但问题是,我不能一次选择带有文件夹的文件,我只能选择文件夹。我不想那样。
可能答案是JSzip,但这似乎并不容易?我试着阅读了他们的文档,但什么都看不懂。我不能100%确定JSzip到底是什么以及它是如何工作的。但你明白了。
您可以获取所有选定的文件/文件夹,并将它们添加到ZIP文件中(使用JSzip(。
使用<input type="file" webkitdirectory>
和<input type="file" multiple>
,可以允许用户选择文件或文件夹。
您需要多个元素,因为您可以上传文件或文件夹,但不能同时上传一个元素。注意:multiple
不能与webkitdirectory
一起使用(是的,webkitdirectory
在Firefox中有效,请参阅:https://www.caniuse.com/mdn-api_htmlinputelement_webkitdirectory)。
因此,当选择了一个文件/文件夹时,你可以将其添加到ZIP文件中,然后一旦添加了你想要的所有内容,你就可以点击按钮上传它。
下面是一个示例,您可以选择要添加到zip中的文件和文件夹。";上传";按钮只会下载文件,因为我无法从这里上传到您的服务器。(注意:saveAs()
功能在本例中可能不起作用。(
let zip = new JSZip(),
// Used to show the file(s) selected
fileNames = document.getElementById('zipData');
Array.from(document.getElementsByClassName('upload')).forEach(u => {
u.addEventListener('change', e => {
let files = e.target.files;
for (let i = 0; i < files.length; i++) {
let file = files[i],
name = file.webkitRelativePath || file.name,
fileName = document.createElement('li');
// Append the name to the list
fileName.appendChild(document.createTextNode(name));
fileNames.appendChild(fileName);
// Add the file to the ZIP file
zip.file(name, file, {binary: true});
}
});
});
document.getElementById('zipUpload').addEventListener('submit', e => {
e.preventDefault();
// ZIP up all the files and get a blob
zip.generateAsync({type: "blob"}).then(blob => {
let ajax = new XMLHttpRequest(),
formData = new FormData();
// Add the blob to the data to be sent to the server
formData.append('zipFile', blob, Date.now() + '.zip');
ajax.upload.addEventListener('progress', function(e) {
let progress = Math.floor(e.loaded / e.total * 100);
console.log('Uploading: ' + progress + '%');
}, false);
ajax.addEventListener('load', function(e) {
if (ajax.readyState === 4 && ajax.status === 200) {
console.log('done.');
}
}, false);
ajax.open('POST', 'https://your.url', true);
// We can't actually upload from here, so just download it instead
//ajax.send(formData);
saveAs(blob, Date.now() + '.zip');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.5.0/jszip.min.js" integrity="sha512-y3o0Z5TJF1UsKjs/jS2CDkeHN538bWsftxO9nctODL5W40nyXIbs0Pgyu7//icrQY9m6475gLaVr39i/uh/nLA==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js" integrity="sha512-Qlv6VSKh1gDKGoJbnyA5RMXYcvnpIqhO++MhIM2fStMcGT9i2T//tSwYFlcyoRRDcDZ+TYHpH8azBBCyhpSeqw==" crossorigin="anonymous"></script>
<form id="zipUpload">
<input class="upload" type="file" multiple>
<input class="upload" type="file" webkitdirectory>
<button type="submit">
Upload your ZIP
</button>
</form>
<ul id="zipData"></ul>