使用Input type=file 原生上传使用总结


最新发现之前项目里用的 js 上传插件有点点问题 就是上传同一张图片会报错图片限制的类型错误 不知道是不是自己参数什么没设置对 然后想到了使用input标签中的type=file这种原生的上传 写下分享下

传统的上传

比如我们在正常的form表单中需要上传一张图片 一般不使用插件之类的常用做法就是先设置form属性 enctype ="multipart/form-data" 最后提交form表单 然后后天那边自己写处理接受存储啥的 但是这样做会直接刷新页面 很多时候我们不希望提交页面这种 一般都会想到ajax之类 当然也有别的方法吧 小弟学渣

Ajax上传

使用ajax上传时 需要把要提交的数据组成key=>value的形式 但是文件流就比较麻烦了 他不能被转换成字符之类 即使你使用serialize 也不能把文件流序列化 然后传送到后端 不过没关系 有个 FormData的玩意可以帮助我们在 ajax 中提交文件流

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”.
大概就是说 FormData 接口提供了一种很方便的方法去构建表单中的 属性=>值 的这种键值对结构 另外他还可以使用 XMLHttpRequest.send() 来发送异步请求 如果设置了 multipart/form-data 还可以使用和form表单一样的格式化(渣渣英文翻译水平勿喷!!!)

1
2
3
4
5
6
7
8
9
1.创建一个formdata对象
var formData = new FormData();
2.添加属性值 append方法有2个版本 一个是传2个参数的 一个是传递3个参数的
①formData.append('key_name','value'); //这种可以用来设置普通的字符串之类的值
②formData.append('key_name','value','file_name'); //这种用来设置 Blob 和 File 类型的值 如果是blob类型的 第三个参数默认写 ‘blob’就行 如果是file 类型 默认就写上传的文件名就行
eg:formData.append('file',myFileInput.files[0],'test.jpg');
3.设置的Key也可以是数组形式
formData.append('userpic[]', myFileInput1.files[0], 'chris1.jpg');
formData.append('userpic[]', myFileInput2.files[0], 'chris2.jpg');

其实我用append()2个参数的也可以提交file 第二个参数直接传递 file 对象就可以了
具体参考 MDN 这里有详细的介绍 包括浏览器的兼容情况等等

通过Ajax使用FormData实现上传图片

html:

1
2
<label for="uploadID_face" class="show_info show_info_face" id="show_info_face">+身份证正面</label>
<input class="hide" type="file" id="uploadID_face" />

我做了一个lable-for的绑定 不用学我
js:

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
$(function(){
$('#uploadID_face').change(function(){
var file=this.files[0]; //这里是获取file对象 id对应了上面的input的id属性 0 表示取的第一个
reader = new FileReader(); //这个filereader对象也是 MDN mozilla里的东东 可以看看
reader.readAsDataURL(file); //这个就是把文件读取成base64的格式 输出成图片的一个url一样的东东可以在本地访问到图片 传递进来的file对象已经被处理过了
//console.log(file);
reader.onload = function( evt ){
var formData = new FormData();
formData.append('file',file);
console.log(reader.result);
new_fileload(formData);
}
});
function new_fileload(formData){
$.ajax({
type:"post",
url:'your upload url',
processData: false,
cache: false,
contentType: false,
data:formData,
success:function(data){
//上传结果的判断以及后续的一些操作 比如上传显示缩略图等
}
});
}
}

上面的ajax中需要注意几个参数
1.processData 设置为false 表示对formdata对象不做处理
2.cache设置为false 表示上传文件不需要缓存
3.contentType设置为false 表示表示不设置该值

然后后台接受处理就好了 因为我上面的formData中设置的名字是file所以后台接受了一个file的变量名 我使用的是PHP

1
2
3
$fileData=$_FILES['file'];
//使用了CurlFile构建了一个后端file文件对象 自己写的上传需要
$file = new CURLFile($fileData['tmp_name'], $fileData['type'], $fileData['name']);

仅供参考


-------------The End-------------