使用 formData() 上传多个文件
Posted
技术标签:
【中文标题】使用 formData() 上传多个文件【英文标题】:Uploading multiple files using formData() 【发布时间】:2012-10-10 23:09:22 【问题描述】:var fd = new FormData();
fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
var xhr = new XMLHttpRequest();
xhr.open("POST", "uph.php");
xhr.send(fd);
uph.php:
var_dump($_FILES['fileToUpload']);
这有效,但显然仅适用于files[0]
。如何使它适用于所选文件?
我尝试删除[0]
,但没有成功。
【问题讨论】:
【参考方案1】:您只需要使用fileToUpload[]
而不是fileToUpload
:
fd.append("fileToUpload[]", document.getElementById('fileToUpload').files[0]);
它会返回一个包含多个名称、大小等的数组...
【讨论】:
这需要循环,并附加每个files[i]
【参考方案2】:
您必须获取文件长度以附加到 JS 中,然后通过 AJAX 请求发送,如下所示
//javascript
var ins = document.getElementById('fileToUpload').files.length;
for (var x = 0; x < ins; x++)
fd.append("fileToUpload[]", document.getElementById('fileToUpload').files[x]);
//PHP
$count = count($_FILES['fileToUpload']['name']);
for ($i = 0; $i < $count; $i++)
echo 'Name: '.$_FILES['fileToUpload']['name'][$i].'<br/>';
【讨论】:
对我不起作用。我想这取决于您的多部分表单将如何处理服务器端。 According to MDNAs with regular form data, you can append multiple values with the same name. For example (and being compatible with PHP's naming conventions by adding [] to the name):
. See Example 3@Phoenix
只返回一个文件
fileToUpload[]
错了,应该是fileToUpload
@HoussemBadri 在我的情况下 fileToUpload
不起作用。正如答案中所建议的那样,它应该是fileToUpload[]
。你的评论花了我一个小时才弄清楚发生了什么。【参考方案3】:
使用 javascript 的方法:
var data = new FormData();
$.each($("input[type='file']")[0].files, function(i, file)
data.append('file', file);
);
$.ajax(
type: 'POST',
url: '/your/url',
cache: false,
contentType: false,
processData: false,
data : data,
success: function(result)
console.log(result);
,
error: function(err)
console.log(err);
)
如果您多次调用 data.append('file', file),您的请求将包含您的文件数组。
From MDN web docs:
“
FormData
接口的append()
方法将一个新值附加到FormData
对象内的现有键上,如果该键不存在,则添加该键。FormData.se
t 和append()
之间的区别在于,如果指定的键已经存在,FormData.set
将用新的值覆盖所有现有值,而append()
会将新值附加到现有值集的结尾。”
我自己使用node.js和multipart handler中间件multer获取数据如下:
router.post('/trip/save', upload.array('file', 10), function(req, res)
// Your array of files is in req.files
【讨论】:
...If you call data.append('file', file) multiple times your request will contain an array of your files...
救了我几个小时的绝望,特别是因为我觉得名字应该是file[]
,但只使用file
并多次调用有效,谢谢!
老兄,你是个传奇,从早上开始就一直在寻找这个,谢谢分配人
我试过你的例子,但是当我 var_dumped 它时,它总是返回集合的最后一个图像。我将:data.append('file', file)
更改为 data.append('file', i)
,这对我有用。
你是我的英雄
这一行是最重要的信息If you call data.append('file', file) multiple times your request will contain an array of your files.
非常感谢。节省了我数小时的时间。【参考方案4】:
这很好用!
var fd = new FormData();
$('input[type="file"]').on('change', function (e)
[].forEach.call(this.files, function (file)
fd.append('filename[]', file);
);
);
$.ajax(
url: '/url/to/post/on',
method: 'post',
data: fd,
contentType: false,
processData: false,
success: function (response)
console.log(response)
,
error: function (err)
console.log(err);
);
【讨论】:
在你的代码中添加一个简短的解释将会得到一个更好的答案!只是一个有用的提示【参考方案5】:这对我有用:
let formData = new FormData()
formData.append('files', file1)
formData.append('files', file2)
【讨论】:
文件必须在循环中追加。【参考方案6】:这个对我有用
//Javascript part
//file_input is a file input id
var formData = new FormData();
var filesLength=document.getElementById('file_input').files.length;
for(var i=0;i<filesLength;i++)
formData.append("file[]", document.getElementById('file_input').files[i]);
$.ajax(
url: 'upload.php',
type: 'POST',
data: formData,
contentType: false,
cache: false,
processData: false,
success: function (html)
);
<?php
//PHP part
$file_names = $_FILES["file"]["name"];
for ($i = 0; $i < count($file_names); $i++)
$file_name=$file_names[$i];
$extension = end(explode(".", $file_name));
$original_file_name = pathinfo($file_name, PATHINFO_FILENAME);
$file_url = $original_file_name . "-" . date("YmdHis") . "." . $extension;
move_uploaded_file($_FILES["file"]["tmp_name"][$i], $absolute_destination . $file_url);
【讨论】:
【参考方案7】:这是针对此问题的 Vanilla JavaScript 解决方案 -
首先,我们将使用Array.prototype.forEach()
方法,如
document.querySelectorAll('input[type=file]')
返回一个类似对象的数组。
然后我们将使用Function.prototype.call()
方法将类数组对象 中的每个元素分配给.forEach
方法中的this
值。
HTML
<form id="myForm">
<input type="file" name="myFile" id="myFile_1">
<input type="file" name="myFile" id="myFile_2">
<input type="file" name="myFile" id="myFile_3">
<button type="button" onclick="saveData()">Save</button>
</form>
JavaScript
function saveData()
var data = new FormData(document.getElementById("myForm"));
var inputs = document.querySelectorAll('input[type=file]');
Array.prototype.forEach.call(inputs[0].files, function(index)
data.append('files', index);
);
console.log(data.getAll("myFile"));
您可以查看同一HERE的工作示例
【讨论】:
【参考方案8】:创建一个FormData
对象
const formData: any = new FormData();
并附加到相同的 keyName
photos.forEach((_photoInfo: localUri: string, file: File ) =>
formData.append("file", _photoInfo.file);
);
并将其发送到服务器
// angular code
this.http.post(url, formData)
这将自动在file
下创建一个对象数组
如果你使用的是 nodejs
const files :File[] = req.files ? req.files.file : null;
【讨论】:
【参考方案9】:我为我找到了这份工作!
var fd = new FormData();
$.each($('.modal-banner [type=file]'), function(index, file)
fd.append('item[]', $('input[type=file]')[index].files[0]);
);
$.ajax(
type: 'POST',
url: 'your/path/',
data: fd,
dataType: 'json',
contentType: false,
processData: false,
cache: false,
success: function (response)
console.log(response);
,
error: function(err)
console.log(err);
).done(function()
// do something....
);
return false;
【讨论】:
请为您的答案添加更多解释【参考方案10】:要上传多个带有角度表单数据的文件,请确保您的 component.html 中有此文件
上传文件
<div class="row">
<div class="col-md-4">
<small class="text-center"> Driver Photo</small>
<div class="form-group">
<input (change)="onFileSelected($event, 'profilepic')" type="file" class="form-control" >
</div>
</div>
<div class="col-md-4">
<small> Driver ID</small>
<div class="form-group">
<input (change)="onFileSelected($event, 'id')" type="file" class="form-control" >
</div>
</div>
<div class="col-md-4">
<small>Driving Permit</small>
<div class="form-group">
<input type="file" (change)="onFileSelected($event, 'drivingpermit')" class="form-control" />
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<small>Car Registration</small>
<div class="form-group">
<div class="input-group mb-4">
<input class="form-control"
(change)="onFileSelected($event, 'carregistration')" type="file"> <br>
</div>
</div>
</div>
<div class="col-md-6">
<small id="li"> Car Insurance</small>
<div class="form-group">
<div class="input-group mb-4">
<input class="form-control" (change)="onFileSelected($event,
'insurancedocs')" type="file">
</div>
</div>
</div>
</div>
<div style="align-items:c" class="modal-footer">
<button type="button" class="btn btn-secondary" data-
dismiss="modal">Close</button>
<button class="btn btn-primary" (click)="uploadFiles()">Upload
Files</button>
</div>
</form>
在您的 componenet.ts 文件中 像这样声明数组选择的文件
selectedFiles = [];
// 所选文件的数组
onFileSelected(event, type)
this.selectedFiles.push( type, file: event.target.files[0] );
//在上传文件方法中,像这样附加你的表单数据
uploadFiles()
const formData = new FormData();
this.selectedFiles.forEach(file =>
formData.append(file.type, file.file, file.file.name);
);
formData.append("driverid", this.driverid);
this.driverService.uploadDriverDetails(formData).subscribe(
res =>
console.log(res);
,
error => console.log(error.message)
);
注意:我希望这个解决方案对你的朋友有用
【讨论】:
【参考方案11】:在附加到 fd 时添加 []
有效,但如果您希望将数据按文件分组,那么我建议您这样做:
var files= document.getElementById('inpFile').files
var fd = new FormData()
for (let i = 0; i < files.length; i++)
fd.append(i, files[i])
现在您的数据将按文件分组发送,而不是按属性分组。
【讨论】:
【参考方案12】:我的工作是这样的:
var images = document.getElementById('fileupload').files;
var formData = new FormData();
for(i=0; i<images.length; i++)
formData.append('files', images[i]);
【讨论】:
【参考方案13】:这对我有用
var ins = $('.file').map(function ()
return this.files;
).get();
for (var x = 0; x < ins; x++)
formData.append("file", ins[x][0]);
【讨论】:
【参考方案14】:如果您正在实例化 FormData 对象,该对象已经将表单作为构造函数参数传递,则输入文件的名称属性必须包含方括号。
HTML:
<form id="myForm" method="POST" action="url" enctype="multipart/form-data">
<input class="form-control form-control-lg" type="file" name="photos[]" multiple />
JS:
var formData = new FormData(document.getElementById('myForm'));
console.log(formData.getAll('photos[]'));
这对我有用!
【讨论】:
【参考方案15】:如果我们在 html 中有输入:
<input id="my-input" type="file" mutliple /> // multiple attribute to select and upload multiple files
我们可以从该输入中获取文件并使用纯 js 脚本将其发送到服务器:
const myInput = document.getElementById('my-input') // getting our input
myInput.addEventListener('change', (event) => // listening for file uploads
const files = event.target.files // getting our files after upload
const formData = new FormData() // create formData
for (const file of files)
formData.append('files', file) // appending every file to formdata
const URL = 'http://server.com:3000'
const response = fetch(URL,
method: 'POST',
data: formData // sending our formdata in body of post request
)
return response.json()
它非常适合我
P.S.:我在后端(node.js + express)使用multer
,添加到文件上传路径
upload.array("files", 10)
第一个参数是我们文件的属性名称(在 formdata 中)
第二个参数是最大文件大小
【讨论】:
域不使用端口(@987654325@),仅适用于本地服务器。 是的,当然,如果您在前端上传图片,您会获取图片并将其发送到带有 host:port 的后端服务器 是的,本地服务器不是域。以上是关于使用 formData() 上传多个文件的主要内容,如果未能解决你的问题,请参考以下文章
[FE] 用 FormData 上传多个文件到 MultipartFile[] 接口