Mig*_*ero 4 javascript php ajax file-upload fetch
我得到了这个上传多个文件的代码,但现在我不知道如何上传包含多个文件的文件夹以及包含更多文件的子文件夹。等正如你所看到的,我正在使用 javscript 来获取和 php 来处理和保存文件,文件现在大约为 2MB 我试图用 foreach 来获得像 $_Folder 一样的东西,但它对我不起作用:/
索引.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Upload Files</title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<input type="file" name="files[]" multiple>
<input type="submit" value="Upload File" name="submit">
</form>
<script src="upload.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
进程.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['files'])) {
$errors = [];
$path = 'uploads/';
$extensions = ['jpg', 'jpeg', 'png', 'gif'];
$all_files = count($_FILES['files']['tmp_name']);
for ($i = 0; $i < $all_files; $i++) {
$file_name = $_FILES['files']['name'][$i];
$file_tmp = $_FILES['files']['tmp_name'][$i];
$file_type = $_FILES['files']['type'][$i];
$file_size = $_FILES['files']['size'][$i];
$file_ext = strtolower(end(explode('.', $_FILES['files']['name'][$i])));
$file = $path . $file_name;
if (!in_array($file_ext, $extensions)) {
$errors[] = 'Extension not allowed: ' . $file_name . ' ' . $file_type;
}
if ($file_size > 2097152) {
$errors[] = 'File size exceeds limit: ' . $file_name . ' ' . $file_type;
}
if (empty($errors)) {
move_uploaded_file($file_tmp, $file);
}
}
if ($errors) print_r($errors);
}
}
Run Code Online (Sandbox Code Playgroud)
上传.js
const url = 'process.php';
const form = document.querySelector('form');
form.addEventListener('submit', e => {
e.preventDefault();
const files = document.querySelector('[type=file]').files;
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
let file = files[i];
formData.append('files[]', file);
}
fetch(url, {
method: 'POST',
body: formData
}).then(response => {
console.log(response);
});
});
Run Code Online (Sandbox Code Playgroud)
期待上传这样的东西
Upload:
-(1Folder)
--Image.png
--Imagen.jpg
--(2Folder)
---Image2.png
--(3Folder)
---Image3.jpg
--Imagen.gif
Run Code Online (Sandbox Code Playgroud)
在现代 Chrome、Firefox 和 Edge 中,您可以设置 html 属性,webkitdiretory
让文件输入变成目录选择窗口。如果您multiple
在选择文件夹后还使用该属性,则所有内容(以及子文件夹中的内容)都将在.files
列表中
<input type="file" webkitdirectory multiple>
Run Code Online (Sandbox Code Playgroud)
然后,您只需使用相同的代码来包含所有要上传的文件。
现在,如果您想保留文件夹结构,您还必须webkitRelativePath
在您选择的文件夹中包含保存该文件的相对路径的 。并使用该路径在服务器上创建文件夹。
for (let i = 0; i < files.length; i++) {
let file = files[i];
let fileParamName = `file${i}`;
let filePathParamName = `filepath${i}`;
formData.append(fileParamName, file);
formData.append(filePathParamName,file.webkitRelativePath);
}
Run Code Online (Sandbox Code Playgroud)
然后在服务器上使用 filePathParamName 创建目录结构并将文件移动到它:
//Just for example
//make sure to used sanitized data in production
$folderpath = $path.dirname($_POST["filepath23"]);
$file = $path.$_POST["filepath23"];
$file_tmp = $_FILES["file23"]["tmp_name"];
//third option is for recursive folder creation (make subfolders)
mkdir($path,0644,true);
move_uploaded_file($file_tmp, $file)
Run Code Online (Sandbox Code Playgroud)
对于更简单的方法,您可以将所有文件放入 javascript 中的 zip 文件中,然后上传单个 zip 文件并在服务器上提取。使用 JSZip和PHP ZipArchive 类:
var zip = new JSZip();
for (let i = 0; i < files.length; i++) {
let file = files[i];
zip.file(file.webkitRelativePath, file);
}
zip.generateAsync({type:"blob"})
.then(function(content) {
formData.append("folderzip",content);
fetch(url, {
method: 'POST',
body: formData
}).then(response => {
console.log(response);
});
});
Run Code Online (Sandbox Code Playgroud)
然后在 php 中将文件夹解压缩到您想要的位置:
move_uploaded_file($file_tmp, $path);
$zip = new ZipArchive();
if($zip->open($path)){
$zip->extractTo($somepath);
$zip->close();
//delete zip file
unlink($path);
}
Run Code Online (Sandbox Code Playgroud)
使用 webkitRelativePath 的文件列表客户端演示:
<input type="file" webkitdirectory multiple>
Run Code Online (Sandbox Code Playgroud)
for (let i = 0; i < files.length; i++) {
let file = files[i];
let fileParamName = `file${i}`;
let filePathParamName = `filepath${i}`;
formData.append(fileParamName, file);
formData.append(filePathParamName,file.webkitRelativePath);
}
Run Code Online (Sandbox Code Playgroud)