This和this答案是我尝试将object
转换为file
类型并附加到FormData的动机:
var fileBag = new FormData();
fileArray.forEach(function(element) {
file_name = element.name;
file_type = element.type;
var file = new File([element], file_name, {type:file_type});
console.log("file type= ", typeof file); // o/p is object
fileBag.append(file_name, file);
});
当我尝试相同时,新创建的文件的类型是转换为文件后的对象(我希望它是文件)。转换前后的File
对象是这样的:
File
lastModified: 1543472205025
lastModifiedDate: Thu Nov 29 2018 11:46:45 GMT+0530 (India Standard Time) {}
name: "testFile.xlsx"
size: 1119910
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
webkitRelativePath: ""
__proto__: File
这是我通过Ajax
发送的方式
$.ajax({
url: '/project/url/',
type: 'POST',
data: {'file': fileBag},
enctype: 'multipart/form-data',
processData: false,
contentType: false,
dataType: "json",
success: function (data) {
console.log("data= ",data);
},
error: (error) => {
console.log(JSON.stringify(error));
}
});
我在Django
和PHP
都试过这个。我得到空数组。我的问题是:
1)转换前后的typeof
会是一样的吗?
2)如何将文件对象数组发送到后端?还有其他解决方案吗?
这是我的codepen相同。
编辑:Codepen代码
var fileArray = [];
var fileBag = new FormData();
function handleFileUpload(event)
{
var fileUploadButtonId = event.currentTarget.id;
var files = document.getElementById(fileUploadButtonId).files;
var fileBag = new FormData();
var arrayOfAllUploadedFiles = Array.from(files);
for(var i=0; i<arrayOfAllUploadedFiles.length; i++)
{
fileArray.push(arrayOfAllUploadedFiles[i]);
}
fileArray.forEach(function(element) {
file_name = element.name;
file_type = element.type;
var file = new File([element], file_name, {type:file_type});
console.log("file type= ", typeof file); // o/p is object. // o/p is object. Shouldn't this be 'file'?
fileBag.append(file_name, file);
alert("filebag= ",fileBag); // this is empty
});
}
转换前后的类型是否相同?
因为“file”不是JavaScript数据类型。一切不是原始的东西都是一个对象。
console.log(typeof 1);
console.log(typeof "1");
console.log(typeof null);
console.log(typeof undefined);
console.log(typeof [1,2,3]);
console.log(typeof {hello: "world"});
console.log(typeof new Date());
console.log(typeof document.body);
console.log(typeof window);
2)如何将文件对象数组发送到后端?还有其他解决方案吗?
你不能发送一个数组。您只能发送一些服务器端代码可以组装成阵列的文本。
对于两个standard encodings supported by forms,PHP将使用其中的数据填充$_POST
。
如果该数据中字段的名称以[]
结尾,PHP将在$_POST
中放置一个数组。
如果将数组传递给jQuery ajax:
data: { someValue: [1, 2, 3] }
然后jQuery将其编码为:
someValue[]=1&someValue[]=2&someValue[]=3
...所以PHP将生成一个数组。
但是,值必须是jQuery理解的东西。它无法处理FormData
对象。
如果你想发送一个FormData
对象(你必须这样做才能发送文件),那么你需要发送它而不是一个对象:
jQuery.ajax({
url: "/foo",
data: a_form_data_object,
processData: false,
contentType: false,
});
你需要processData
所以它不会尝试转换FormData对象(即所以它会让XMLHttpRequest这样做)。你需要contentType
来阻止它覆盖从FormData对象生成的XMLHttpRequest。
那么为了发送数组,我们回到上面描述的规则。你说:
fileBag.append(file_name, file);
但要获得一个数组,你需要一个以[]
结尾的名字。
fileBag.append("myname[]", file);
最后,在你的问题中看不到,但看着你的codepen。这将为您提供一组文件:
document.getElementById(fileUploadButtonId).files;
由于它们是文件,因此使用代码将它们转换为文件是没有意义的。
您可以简化代码:
var fileBag = new FormData();
var files = document.getElementById(fileUploadButtonId).files;
var arrayOfAllUploadedFiles = Array.from(files);
fileArray.forEach(file => fileBag.append("myname[]", file);
jQuery.ajax({
url: "/foo",
data: fileBag,
processData: false,
contentType: false,
});