本文主要讨论以下两部分:
一、实现图片及时预览,将用户选中的图片及时显示在前台页面(利用FileReader实现);不用通过后台接口返回的图片地址赋值给src再展示到前台,减少前后台的频繁交互;
二、通过后台接口,将图片上传到服务器中(FormData)。
首先介绍一下h5新增的FileReader对象():
FileReader:读取文件内容
1. readAsText(): 读取文本文件(可以使用Txt打开的文件),返回文本字符串,默认编码是UTF-8 2. readAsBinaryString(): 读取任意类型的文件。返回二进制字符串。这个方法不是用来读取文件展示给用户看,而是存储文件。例如:读取文件的内容,获取二进制数据,传递给后台,后台接收了数据之后,再将数据存储 3. readAsDataURL(): 读取文件获取一段以data开头的字符串,这段字符串的本质就是DataURL.DataURL是一种将文件(这个文件一般就是指图像或者能够嵌入到文档的文件格式) 嵌入到文档的方案。DataURL是将资源转换为base64编码的字符串形式,并且将这些内容直接存储在url中>>优化网站的加载速度和执行效率。 4. abort():中断读取 FileReader 提供一个完整的事件模型,用来捕获读取文件时的状态 - onabort: 读取文件中断片时触发 - one rror: 读取错误时触发 - onload: 文件读取成功完成时触发 - onl oadend: 读取完成时触发,无论成功还是失败 - onl oadstart: 开始读取时触发 - onprogress: 读取文件过程中持续触发具体可以参考 https://www.cnblogs.com/hhhyaaon/p/5929492.html ,介绍的很详细。
一、实现图片及时预览
首先是html代码:
1 <form action="" enctype="multipart/form-data" method="post" name="form1" id="form1"> 2 文件:<input type="file" name="myFile" id="myFile" onchange="getFileContent();" multiple> 3 <!-- 进度条 --> 4 <div></div> 5 <input type="submit"> 6 </form>
7 <!-- 图片展示区域 --> 8 <ul id="imgList"></ul>
css样式:
1 <style> 2 ul{ 3 list-style: none; 4 } 5 li{ 6 float: left; 7 border: 1px solid #000; 8 margin: 10px; 9 } 10 li img{ 11 display:block; 12 } 13 div{ 14 width: 0%; 15 height: 20px; 16 background-color: lightcoral; 17 } 18 </style>
页面效果是这样子:
1、上传 单个图片 的js代码:
1 function getFileContent(){ 2 // file[0]就是上传的图片本身 3 // FileReader的readAsDataURL方法可以将图片转换为base64格式 4 // 1.上传单个文件时: 5 var reader = new FileReader(); 6 var file = document.querySelector("#myFile").files; 7 reader.readAsDataURL(file[0]); 8 // 一定要在文件读取 成功完成时 再进行相应的操作: 9 reader.onload = function(){ 10 document.querySelector("img").src = reader.result; 11 } 12 }
其中file打印出是:里面包含用户上传的文件名称、大小、类型,如果想限制图片大小和类型,可以自行添加判定条件~
2、上传 多个图片 的js代码:
每上传一张图片(一个文件)就需要创新创建一个 FileReader 实例,否则会出现一些问题(只成功上传了选中的最后一张图片);
这里将上传单个图片封装为一个函数,在循环遍历用户选择的文件时,一一上传图片,每个图片都有上传时的进度条。
1 function getFileContent(){ 2 // 上传多个文件时: 3 var file = document.querySelector("#myFile").files; 4 var totalSize = 0; 5 // 限定文件总数不能超过的大小 6 var maxSize = 10*1024*1024; 7 for(var i=0;i<file.length;i++){ 8 totalSize += file[i].size; 9 if(file[i].size > maxSize){ 10 alert("文件不能超过10M") 11 return false; 12 }else{ 13 // 调用上传多个图片的方法,传入的参数为:用户选中的文件 和 每个图片的 index 14 uploadMultiImg(file,i); 15 } 16 } 17 } 18 19 // 上传多个图片的方法: 20 function uploadMultiImg(file,index){ 21 var li = document.createElement("li"); 22 ul.appendChild(li); 23 var img = document.createElement("img"); 24 li.appendChild(img); 25 /*1.1 由于IE9以下没有FileReader,因此先判断是否支持FileReader 并且 创建文件读取对象*/ 26 if(window.FileReader) { 27 var reader = new FileReader(); 28 } else { 29 alert("您的设备不支持图片预览功能,如需该功能请升级您的设备!"); 30 } 31 // 1.2 是否是图片 32 var imageType = /^image\//; 33 if(!imageType.test(file[index].type)) { 34 alert("请选择图片!"); 35 return; 36 } 37 /*2.读取文件,获取DataURL 38 * 2.1.说明没有任何的返回值:void:但是读取完文件之后,它会将读取的结果存储在文件读取对象的result中 39 * 2.2.需要传递一个参数 binary large object:文件(图片或者其它可以嵌入到文档的类型) 40 * 2.3:文件存储在file表单元素的files属性中,它是一个数组*/ 41 reader.readAsDataURL(file[index]); 42 /*获取数据*/ 43 reader.onload = function(){ 44 /*展示:图片路径设置为读取的图片*/ 45 img.src = reader.result; 46 img.style.width = '300px'; 47 img.style.height = '300px'; 48 } 49 50 // 进度条 51 reader.onprogress = function(e){ 52 var percent = e.loaded / e.total * 100 + '%'; 53 div.style.width = percent; 54 var number = (e.loaded / e.total * 100).toString().substring(0,5) + '%'; 55 div.innerText = number; 56 } 57 }
进度条是通过reader.onprogress()方法实现,打印e:loaded是已上传的大小,total是文件总大小。通过二者的比例可以自定义一个进度条。
最终效果:
二、将图片上传到服务器中(FormData对象)
参考文章:
https://blog.csdn.net/lijia_1983370657/article/details/80489979
https://blog.csdn.net/thunderevil35/article/details/80953236
https://www.cnblogs.com/hutuzhu/p/4409292.html
使用 h5的 formData 对象 用ajax异步的方式提交form表单(还可以实现异步提交文件)
在使用 jquery 发送图片到后台时要注意几点:
- <form>标签添加 enctype="multipart/form-data" 属性
- jQuery 的 ajax 中 processData 设置为 false (表示不需要对数据做处理)
- jQuery 的 ajax 中 cache 设置为 false (表示上传文件不需要缓存)
- jQuery 的 ajax 中 contentType 设置为 false (因为前面已经声明了是‘FormData对象’)
如果没有<form>
标签,也没有 enctype="multipart/form-data"
属性,可以使用 FormData 的 append() 方法来手动添加 如用户名、文件等内容。
1 var formData = new FormData($('#form1')); 2 // formData.append('images', $('#myFile')[0].files); 3 //ajax请求 4 $.ajax({ 5 type: "post", 6 url: "接口地址", 7 data: formdata, 8 dataType: 'json', 9 processData: false, // 告诉jQuery不要去处理发送的数据 10 contentType: false, // 告诉jQuery不要去设置Content-Type请求头 11 xhrFields:{withCredentials:true}, 12 async: true, //默认是true:异步,false:同步。 13 success: function (data) { 14 callback(data); 15 }, 16 error: function (data) { 17 layer.msg('请求异常'); 18 }, 19 });
如果使用原生js实现,如下代码:
1 function fsubmit() { 2 var form=document.getElementById("form1"); 3 var formData=new FormData(form); 4 var oReq = new XMLHttpRequest(); 5 oReq.onreadystatechange=function(){ 6 if(oReq.readyState==4){ 7 if(oReq.status==200){ 8 var json=JSON.parse(oReq.responseText); 9 var result = ''; 10 // result += 'name=' + ret['name'] + '<br>'; 11 // result += 'gender=' + ret['gender'] + '<br>'; 12 result += '<img src="' + json['photo'] + '" width="100">'; 13 $('#result').html(result); 14 } 15 } 16 } 17 oReq.open("POST", "server.php"); 18 oReq.send(formData); 19 return false; 20 }