过程分析
图片上传主要分成三部分:
一、本地表单处理
- 1、表单美化
- 2、获取上传文件信息(选择、拖拽、一张、多张)
- 3、图片信息校验(格式、大小)
- 4、本地展示
二、调用接口获取上传需要的参数
- 1、引入cos-js-sdk-v5(jquery、axios如果必要)
- 2、ajax\jsonp,获取bucket\region\appid参数
三、上传图片
- 1、创建cos实例
- 2、上传,上传成功后清空表单,进度监控(如果必要)
- 3、将获取的图片url上传到数据库,其他处理,放大效果等
本地上传控件处理
表单美化
上传控件一般需要美化,比如可以用label标签,显示样式,把input标签做透明处理,宽高设置为0,outline:none,接着就可以随心所欲的美化了。
<div>
<label for="file" class="demo">上传</label><input class="selImg" type="file" id="file" onchange="handleFiles(this.files)" multiple="multiple" > <!--如果需要显示本地图片--> <!-- <img id="showImg" src="" alt=""> --> </div> <style> input{outline:none;background:transparent;width:0;height:0;} .demo{border:1px solid #999;background:#999;color:#fff;border-radius:5px;display:block;width:100px;height:30px;text-align: center;line-height: 30px;} </style>
获取上传文件信息
这里我们处理选择图片,兼容一张和多张
// 选择图片
function handleFiles (files) { console.info(files)//打印出来信息见图1 checkPic(files); } // 拖拽图片 function handleFiles1 (files) { console.info(files) checkPic(files); } // 获取到图片的名称、大小、图片格式等
图一:
图片信息校验
function checkPic (files) {
var fileList = []; // 如果只需要单张上传,去掉multiple="multiple",直接获取数组第1个元素即可file = files[0]; // 如果是允许多张上传,将上传的图片放入数组中,循环数组 if (files.length === 0) { return } else { for(var i=0; i<files.length; i++){ fileList.push(files[i]); } } //循环待上传的图片 fileList.forEach((item) => { // 1 校验上传图片格式 if(!/\.(jpg|jpeg|png|JPG|PNG)$/.test(item.name)){ alert('仅支持png,jpeg,jpg格式图片'); return } //校验上传图片大小 var size = item.size/1024; if(size>5000){ alert('图片最大不能超过5M'); return } // 上传 // upload(obj,item) }) }
本地展示
function showImg (file) {
var imgURL = ''; try{ imgURL = file.getAsDataURL(); }catch(e){ imgRUL = window.URL.createObjectURL(file); } return imgRUL; }
调用接口获取上传需要的参数
引入cos-js-sdk-v5
npm i cos-js-sdk-v5 或
<script src="cos-js-sdk-v5.js"></script>
获取bucket\region\appid参数
这些参数是从腾讯云配置存储桶时,带有的。调试的时可放在前端,部署时需要放在后端。
一般腾讯云存储都需要用到跨域,这里可以在腾讯云配置允许访问的域名。
后台现在使用的时jsonp请求接口。
// 封装原生的ajax
function ajax(opt) { opt = opt || {}; opt.method = opt.method.toUpperCase() || 'POST'; opt.url = opt.url || ''; opt.async = opt.async || true; opt.data = opt.data || null; opt.success = opt.success || function () {}; var xmlHttp = null; if (XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } else { xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); }var params = []; for (var key in opt.data){ params.push(key + '=' + opt.data[key]); } var postData = params.join('&'); if (opt.method.toUpperCase() === 'POST') { xmlHttp.open(opt.method, opt.url, opt.async); xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); xmlHttp.send(postData); } else if (opt.method.toUpperCase() === 'GET') { xmlHttp.open(opt.method, opt.url + '?' + postData, opt.async); xmlHttp.send(null); } xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { opt.success(xmlHttp.responseText); } }; } // 调用ajax function http () { ajax({ method: 'GET', url: 'http://localhost/users/cosV5', success: function(res) { obj = JSON.parse(res); console.info('res', obj) } }) } // 这里返回的参数见下图,后面new COS 时需要用到。
上传图片
创建cos实例
由于图片过多,如果不去重命名图片,会导致图片太乱,可以定义函数,重置图片名称。
Key 的值如果加上 /pic, 系统会默认放在pic文件夹下面。
// obj为上一步请求的配置参数
function upload (obj,file) { var cos = new COS({ AppId: obj.appId, SecretId: obj.secretId, SecretKey: obj.secretKey, }); cos.sliceUploadFile({ Bucket: obj.bucket, Region: obj.region, Key:'/pic/'+file.name, //上传的文件夹和图片名称 Body: file, //要上传的文件 onProgress: function (progressData) { /* 上传进度 */ } }, function (err, data) { console.log(err, data); // 上传成功返回url // 需要清空上传控件,方法见下一步 }); }
返回参数说明
上传成功后处理
这里如果没有清理控件,会出现当第二次选择同一张图片时,由于图片相同,无法触发onchange事件,导致无法上传,这里的解决办法是将file的value值设置为空或重新初始化
如果不能访问可能是权限的问题,可以在腾讯云存储桶配置权限,解决方法见图三
//清空上传控件的值id
function clearInput (ele) { var demo = document.getElementById(ele); if (demo.outerHTML) { demo.outerHTML = demo.outerHTML; } else { // FF(包括3.5) demo.value = ""; } }
图三:
注意点:
- 1、上传成功后一定要清空表单,防止上传同一张图片失败;
- 2、cos-js-sdk-v5版本和cos-js-sdk-v4调用方法不同
- 3、使用a标签注意阻止默认事件
- 4、input是h5兼容性的标签,所以对不支持h5的标签不支持
- 5、腾讯云参考文档https://cloud.tencent.com/document/product/436/11459