之前项目做文件上传(本篇着重讲纯图片上传)的时候,一般都是用的flash插件。
H5的input标签提供了type=file的文件上传功能,那么如何用这个标签实现前后端之间的文件上传呢。
百度了一下,一个能用的都没有,都有BUG,讲的也很复杂,好气喔,自己写吧!
先看部分代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>H5input标签上传文件</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<input type="file" name="image" accept="image/*" onchange="uploadImg()">
<script type="text/javascript">
function uploadImg(event) {
var e=window.event||event;
// 获取当前选中的文件
var oFile = e.target.files[0];
console.log(oFile);//打印值看下面图片,简单点的话我们直接把这个数据给后台处理就可以了
//接下来按照跟后台约定好的进行数据交互就可以-不使用jq的话这里有一些细节,稍后解释
$.post("约定好的url地址",oFile,function(result){
console.log(result);
})
}
</script>
</body>
</html>
上面console.log(oFile);
这一行代码打印的结果如下:
简单点,写博客的方式简单点,不要为了显摆自己的技术写一堆API文档都可以查到的东西。
这里给想深入了解的H5上传的同学三个相关的知识链接(没错,MDN上的API描述):
上面只是一个简陋的方案(但完全可用),接下来让我们完善一下!
既然做的是单张图片上传功能,这里我在input标签上加了一个accept="image/*"
做了一个基本的类型限制,这样你在选择文件的时候你会发现你能选择文件类型是图片文件。
我们可以自定义可上传的文件类型,用如下方式指定多种类型: <input type="file" accept=".doc,.docx,.pdf,.txt,.htm,.html" />
但是这并不能防止用户的恶意操作(主要是堵住测试和后台的嘴,☺),另外就算是选择类型是图片的话,其实还是可以选择少部分其它格式例如.zip。
利用之前给展示过的oFile打印结果中的type
字段
// 检查上传文件类型--添加到发送数据之前
if(['jpeg', 'png', 'gif', 'jpg'].indexOf(oFile.type.split("/")[1]) < 0) {
// alert太ugly了,用你们系统的报错弹窗就行(如果有)
alert("上传的文件必须是图片格式");
return;
}
好,图片的格式算是限制了,数组里面没涉及到的格式你自己往里面加。
额外补充一点,你会发现当我要做上传所有类型的文件时,通过oFile.type
去判断文件类型好像有点问题,那么这里我提供一个稳妥的办法,我们通过oFile.name
去判断,代码如下:
// 限制文件类型
var fileType = oFile.name.substr(oFile.name.lastIndexOf(".")+1);
if (['doc', 'docx', 'pdf', 'txt', 'htm', 'html'].indexOf(fileType) < 0) {
alert("只支持.doc .docx .pdf .txt .htm .html格式文件");
return;
}
上传文件的大小也限制一下,前端做限制很简单,利用之前oFile打印结果中的size
字段,这里API给我们返回的是所选文件的字节数,1KB=1024字节,1MB=1024KB。利用以上,我们加个判断:
var imgMaxSize = 1024 * 1024 * 4; // 4MB图片的字节数
if(oFile.size>imgMaxSize){
alert("您可上传文件的最大限制为4MB");
return;
}
如果你用的是jquery.ajax,并且你上传的是文档文件,可能ajax会对你的文件进行预处理,然后你就可能遇到如下错误: Illegal invocation
这时候我们在ajax里面配置一下选项processData:false
, 关掉jquery的预处理就行了,一般这种问题多发生在文档文件上。
$.ajax({
type:'POST',
url:url,
data:formData,
contentType:undefined,
processData:false,
success:function(data){}
});
还有一些东西,例如图片上传前压缩啊什么的,不想写长篇,这里先不讲了,在这里放一个简单完整版的代码,方便我自己以后copy,你们要用自己拿,别客气!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>H5-input标签上传文件</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<input type="file" accept="image/*" onchange="uploadImg()">
<script type="text/javascript">
function uploadImg(event) {
var e = window.event || event;
var oFile = e.target.files[0];
//console.log(oFile);
var imgMaxSize = 1024 * 1024 * 4; //4MB
// 限制文件类型
if(['jpeg', 'png', 'gif', 'jpg'].indexOf(oFile.type.split("/")[1]) < 0) {
alert("仅可以上传图片格式文件");
return;
}
//限制大小
if(oFile.size > imgMaxSize) {
alert("文件最大为4MB");
return;
}
var data=new FormData();
data.append("filesData",file);//这里不管怎样,我决定还是用formdata的方式上传。
$.post("约定地址",data,function(result){
console.log(result);
})
}
</script>
</body>
</html>