我正在使用XMLHttpRequest和FormData创建上传机制。但是,在创建请求时,文件会以某种方式添加两次,我在这里缺少什么?
我有一个班级Uploader
负责提交多部分表单和一个负责实际上传的静态对象cc
。
当单个输入字段调度Uploader
事件时,将从JS调用change
- 类的上传方法。
Uploader
类如下所示:
class Uploader {
constructor(form){
this._form = form;
this._files = [];
}
_buildFileIndex(){
const fileInputsEl = this._form.querySelectorAll('input[type="file"]');
const fileInputs = Array.from(fileInputsEl).map(input => {
return {
'name': input.getAttribute('name') || 'undefined',
'files': input.files
}
});
this._fileInputs = fileInputs;
return fileInputs;
}
_buildFormData(){
this._formData = new FormData(this._form);
for(let input of this._fileInputs){
for(let file of input.files){
this._formData.append(input.name, file, file.name);
}
}
return this._formData;
}
upload(callback){
this._buildFileIndex();
this._buildFormData();
cc.POST('/api/upload', this._formData, res => {
if(typeof callback === 'function') callback(res);
});
}
}
cc
对象:
const cc = {
'serverADDR': function(){return window.location.protocol + '//' + window.location.host},
'POST': function(endpoint, data, callback, contentType){
const xhttp = new XMLHttpRequest();
xhttp.open('POST', cc.serverADDR() + endpoint, true);
if(contentType) xhttp.setRequestHeader('Content-Type', contentType);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if(typeof callback === 'function') callback(this);
}
};
xhttp.send(data);
}
}
这是根据Google Chrome发送的数据,只在一个输入中选择一个文件:
------WebKitFormBoundaryEDgRU4CNKJQjnIA8
Content-Disposition: form-data; name="media"; filename="Skärmavbild 2017-10-29 kl. 12.16.50.png"
Content-Type: image/png
------WebKitFormBoundaryEDgRU4CNKJQjnIA8
Content-Disposition: form-data; name="media"; filename="Skärmavbild 2017-10-29 kl. 12.16.50.png"
Content-Type: image/png
------WebKitFormBoundaryEDgRU4CNKJQjnIA8--
表单的提交是在特定于页面的对象home
中进行的:
const home = {
'el': {
'inputs': {
'form': document.querySelector('form'),
'input': document.querySelector('input')
}
},
'init': function(){
home.setupForm();
},
'setupForm': function(){
home.el.inputs.input.addEventListener('change', home.upload);
},
'upload': function(){
const uploader = new Uploader(home.el.inputs.form);
uploader.upload(res => {
console.log(res);
});
}
}
home.init();
...表单本身就像:
<form method="POST" action="#">
<input type="file" name="media">
</form>
答案 0 :(得分:0)
创建FormData实例会自动附加提供的表单的字段。因此,在发送请求之前,所有文件都被添加了两次。