I am Oliver

使用 formData 提交表单和上传图片

最近做了一个表单,需要提交好多信息和一些图片,后台的同学说要图片随着表单一起提交。那就不能用 ajax 单张上传了~

图片的话,最多可以选8张,选中了的也可以取消掉,因为并没有传到服务器,所以删除很easy。

然后我就想到了可以用 FormData 来做,因为之前好像用过,感觉很方便。

FormData

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to “multipart/form-data”.

如果使用 jQuery 提交 formData 的话,大致像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$.ajax({
url : url,
type : 'POST',
data : formData,
// 下面这两条需要特别注意
processData: false,
contentType: false,
success(data) {
// ...
},
error(xhr) {
// ...
}
});

就是把 formData 作为 data 发送到后台就好了,如果要构造一个 formData 对象的话,也很简单呢

1
2
3

var formdata = new FormData();
formData.append('ticket_id', 1);

如果放文件在 formData 里面的话呢,也没有太复杂的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// html
// <input
// ref="input-image"
// accept="image/*"
// onChange={ this.onImageSelected }
// type="file"
// />

// ....
isImage: function (file) {
// (!src.type.match(/image.*/)
var type = '|' + file.type.slice(file.type.lastIndexOf('/') + 1) + '|';
return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
},

onImageSelected(e) {
var file = e.target.files[0];
console.log('select image', file);

if (!this.isImage(file)) {
Modal.error({ title: '请选择一张图片' });
return;
}

this.props.onImageSelected(file);
}
// ...

// 放多个也可以~
formData.append('file1', file1)
formData.append('file2', file2)

对了,因为我把上传文件的 input 隐藏掉了,显示出来了是一个 加号 的图标,所以如果要触发 input 的点击事件的话:

1
2
3
4
onItemClick() {
const input = findDOMNode(this.refs['input-image']);
input.click();
},

生成 formData

一个一个的 append 可能速度太慢了,而且需要每个都写一遍,其实生成的 formData 的方式还是蛮多的:

1
2
3
4
5
6
7
// 1
var form = document.getElementById("form");
var formdata = new FormData(form);

// 2
var form = document.getElementById("form");
var formdata = form.getFormData();

好了,没了。

打赏