本文目标

封装一个直传阿里云OSS云存储图片上传控件

控件效果图

上传之前

上传成功

预览图片

文件上传前后台及阿里云存储数据流转过程

1、前端先访问后台接口获取上传阿里云存储权限相关信息和文件编号信息2、前端获取到权限信息之后将文件上至阿里云存储3、前端上传完成之后 提示用户上传完成4、阿里云存储将上传结果异步通知到后端接口5、后端接口将该文件的上传信息入库保存

代码

前端代码

html代码

<table style="width: 70%;text-align:left" class="pull-left"><tr><td rowspan="2"><div id="uploadImage"><div class="statusBar" style="display:none;"><div class="progress"><span class="text">0%</span><span class="percentage"></span></div><div class="info"></div></div><div class="queueList" style="display: flex;width: 204px;"><img id="showImage" src="/static/images/yyzz.jpg"></div></div></td><td style="padding-left:10px;padding-top:10px"><label>原件扫描上传,图片大小不超过5M,文件格式为jpg、jpeg</label><div class="btns"><div id="filePicker"></div><div class="uploadBtn"></div><input type="hidden" id="licenseImgUrl" name="licenseImgUrl"/></div></td></tr>
</table>

引用的资源文件

<link rel="stylesheet" type="text/css" href="/static/common/webuploader.css"/>
<link rel="stylesheet" type="text/css" href="/static/common/customerUploader-shiming.css"/>
<script src="/static/common/webuploader.js"></script>
<script type="text/javascript" src="/static/common/crypto1/hmac/hmac.js"></script>
<script type="text/javascript" src="/static/common/crypto1/crypto/crypto.js"></script>
<script type="text/javascript" src="/static/common/crypto1/sha1/sha1.js"></script>
<script type="text/javascript" src="/static/common/base64.js"></script>
<script type="text/javascript" src="/static/common/upload.js"></script>

js代码

<script>var getExplorer = (function() {var explorer = window.navigator.userAgent,compare = function(s) { return (explorer.indexOf(s) >= 0); },ie11 = (function() { return ("ActiveXObject" in window) })();if (compare("MSIE") || ie11) { return 'ie'; }else if (compare("Firefox") && !ie11) { return 'Firefox'; }else if (compare("Chrome") && !ie11) { return 'Chrome'; }else if (compare("Opera") && !ie11) { return 'Opera'; }else if (compare("Safari") && !ie11) { return 'Safari'; }})()$(function(){var $ = jQuery,$wrap = $('#uploadImage'),// 图片容器$queue = $('<ul class="filelist"></ul>').appendTo( $wrap.find('.queueList') ),// 状态栏,包括进度和控制按钮$statusBar = $wrap.find('.statusBar'),// 文件总体选择信息。$info = $statusBar.find('.info'),// 上传按钮$upload = $wrap.find('.uploadBtn'),// 没选择文件之前的内容。$placeHolder = $wrap.find('img'),// 总体进度条// $progress = $statusBar.find('.progress').hide(),// 添加的文件数量fileCount = 0,// 添加的文件总大小fileSize = 0,// 优化retina, 在retina下这个值是2ratio = window.devicePixelRatio || 1,// 缩略图大小thumbnailWidth = 1000 * ratio,thumbnailHeight = 800 * ratio,// thumbnailBigWidth = 600 * ratio,// thumbnailBigHeight = 400 * ratio,// 可能有pedding, ready, uploading, confirm, done.state = 'pedding',// 所有文件的进度信息,key为file idpercentages = {},supportTransition = (function(){var s = document.createElement('p').style,r = 'transition' in s ||'WebkitTransition' in s ||'MozTransition' in s ||'msTransition' in s ||'OTransition' in s;s = null;return r;})(),// WebUploader实例uploader;var objdata = {};if ( !WebUploader.Uploader.support() ) {alert( 'Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器');throw new Error( 'WebUploader does not support the browser you are using.' );}// 实例化uploader = WebUploader.create({auto:true,pick: {id: '#filePicker',label: '点击选择图片'},// dnd: '#uploadImage .queueList',// paste: document.body,accept: {title: 'Images',extensions: 'jpg,jpeg',mimeTypes: 'image/jpg,image/jpeg'},// swf文件路径swf: "/static/common/Uploader.swf",disableGlobalDnd: false,chunked: false,// server: 'http://webuploader.duapp.com/server/fileupload.php',// server: 'http://2betop.net/fileupload.php',method: 'POST',server: 'xxxxx',//这里要换成你自己的后台接口访问地址fileNumLimit: 1,threads:1,fileSizeLimit: 1*5 * 1024 *1024,    // 文件上传总大小fileSingleSizeLimit: 5 * 1024 * 1024,    // 单个文件大小duplicate:true,                          //允許重複上傳compress:false,thumb: {allowMagnify: false,quality: 85,crop:false,type: 'image/jpeg'},resize:false});uploader.on('uploadBeforeSend',function (obj,data,headers) {$.ajax({type: "post",url: "${ctx}/upload/getOssSign",data:{type:4,originName:obj.file.name},async: false,success: function (re) {var r = JSON.parse(re);objdata.upfileEndPoint = r.endpoint;objdata.bucketName = r.bucketName;objdata.ossSign = {'key': r.dir,'policy': r.policy,'OSSAccessKeyId': r.accessid,'success_action_status': '200','signature': r.signature,'callback':r.callback,'guid':r.guid}}});data = $.extend(data, objdata.ossSign);data.key = objdata.ossSign.key + calculate_object_name(data.name, 'random_name');obj.file.filepath=data.key;obj.filepath = data.key;objdata.filepath = data.key;obj.bucketName = objdata.bucketName;obj.endPoint = objdata.upfileEndPoint;obj.file.bucketName = objdata.bucketName;obj.file.endPoint = objdata.upfileEndPoint;obj.file.guid=objdata.ossSign.guid;$("#licenseImgUrl").val(objdata.ossSign.guid);$("#licenseImgUrl").attr("data",objdata.filepath);// file.path = data.key;headers['Access-Control-Allow-Origin'] = "*";// headers['Content-disposition'] = "inline";});// 添加“添加文件”的按钮,// uploader.addButton({//   id: '#filePicker2',//     label: '继续添加'// });// 当有文件添加进来时执行,负责view的创建function addFile( file ) {var $li = $( '<li id="' + file.id + '">' +'<p class="title" style="display: none;">' + file.name + '</p>' +'<p class="imgWrap"></p>'+'<p class="progress"><span></span></p>' +'</li>' ),$btns = $('<div class="file-panel">' +'<span class="cancel">删除</span>' +'<span class="rotateRight">向右旋转</span>' +'<span class="rotateLeft">向左旋转</span></div>').appendTo( $li ),$prgress = $li.find('p.progress span'),$wrap = $li.find( 'p.imgWrap' ),$info = $('<p class="error"></p>'),showError = function( code ) {switch( code ) {case 'exceed_size':text = '文件大小超出';break;case 'interrupt':text = '上传暂停';break;default:text = '上传失败,请重试';break;}$info.text( text ).appendTo( $li );};if ( file.getStatus() === 'invalid' ) {showError( file.statusText );} else {// @todo lazyload$wrap.text( '预览中' );uploader.makeThumb( file, function( error, src ) {if ( error ) {$wrap.text( '不能预览' );return;}var img = $('<img src="'+src+'" data="'+objdata.filepath+'" onclick="showBigImg(this)"/>');$wrap.empty().append( img );}, thumbnailWidth, thumbnailHeight );percentages[ file.id ] = [ file.size, 0 ];file.rotation = 0;}file.on('statuschange', function( cur, prev ) {if ( prev === 'progress' ) {$prgress.hide().width(0);} else if ( prev === 'queued' ) {      //如果进入队列则取消删除$li.off( 'mouseenter mouseleave' );$btns.remove();}if (cur == 'complete'){$btns = $('<div class="file-panel">' +'<span class="cancel">删除</span>' +'<span class="rotateRight">向右旋转</span>' +'<span class="rotateLeft">向左旋转</span></div>').appendTo( $li );$li.on( 'mouseenter', function() {$btns.stop().animate({height: 30});});$li.on( 'mouseleave', function() {$btns.stop().animate({height: 0});});$btns.on( 'click', 'span', function() {var index = $(this).index(),deg;switch (index) {case 0:uploader.removeFile(file);$("#showImage").show();$("#filePicker").show();$(".uploadBtn").empty();$("#licenseImgUrl").val('');uploader.getStats().successNum = 0;return;case 1:file.rotation += 90;break;case 2:file.rotation -= 90;break;}});}// 成功if ( cur === 'error' || cur === 'invalid' ) {console.log( file.statusText );showError( file.statusText );percentages[ file.id ][ 1 ] = 1;} else if ( cur === 'interrupt' ) {showError( 'interrupt' );} else if ( cur === 'queued' ) {percentages[ file.id ][ 1 ] = 0;} else if ( cur === 'progress' ) {$info.remove();$prgress.css('display', 'block');} else if ( cur === 'complete' ) {$li.append( '<span class="success"></span>' );}$li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );});$li.on( 'mouseenter', function() {$btns.stop().animate({height: 30});});$li.on( 'mouseleave', function() {$btns.stop().animate({height: 0});});$btns.on( 'click', 'span', function() {var index = $(this).index(),deg;switch ( index ) {case 0:uploader.removeFile( file );// enbaleSubmit();return;case 1:file.rotation += 90;break;case 2:file.rotation -= 90;break;}if ( supportTransition ) {deg = 'rotate(' + file.rotation + 'deg)';$wrap.css({'-webkit-transform': deg,'-mos-transform': deg,'-o-transform': deg,'transform': deg});} else {$wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');}});$li.appendTo( $queue );}// 负责view的销毁function removeFile( file ) {var $li = $('#'+file.id);delete percentages[ file.id ];$("#licenseImgUrl").val('');updateTotalProgress();$li.off().find('.file-panel').off().end().remove();}function updateTotalProgress() {}function updateStatus() {}function setState( val ) {var file, stats;if ( val === state ) {return;}$upload.removeClass( 'state-' + state );$upload.addClass( 'state-' + val );state = val;switch ( state ) {case 'pedding':uploader.refresh();break;case 'ready':$statusBar.removeClass('element-invisible');uploader.refresh();break;case 'uploading':// $( '#filePicker2' ).addClass( 'element-invisible' );// $progress.show();// $upload.text( '暂停上传' );$upload.text( '点击选择图片' ).removeClass("state-uploading").addClass("disabled");break;case 'paused':// $progress.show();// $upload.text( '继续上传' );$upload.text( '点击选择图片' ).removeClass("state-paused").addClass("disabled");break;case 'confirm':// $progress.hide();$upload.text( '点击选择图片' ).addClass( 'disabled' );stats = uploader.getStats();if ( stats.successNum && !stats.uploadFailNum ) {setState( 'finish' );return;}break;case 'finish':if (fileCount == 0){$("#filePicker").show();$(".uploadBtn").empty();$("#showImage").show();}else {$("#filePicker").hide();$(".uploadBtn").text("上传成功");$("#showImage").hide();$(".uploadBtn").css("color","green");}break;}updateStatus();}uploader.onUploadProgress = function( file, percentage ) {var $li = $('#'+file.id),$percent = $li.find('.progress span');$percent.css( 'width', percentage * 100 + '%' );percentages[ file.id ][ 1 ] = percentage;// updateTotalProgress();};uploader.onFileQueued = function( file ) {if (fileCount == 0){fileSize = 0;}fileCount++;fileSize += file.size;// if ( fileCount === 1 ) {//    $placeHolder.addClass( 'element-invisible' );//   $statusBar.show();// }addFile( file );$("#showImage").hide();$upload.text( '开始上传' ).removeClass( 'disabled' );setState( 'ready' );updateTotalProgress();};uploader.onFileDequeued = function( file ) {fileCount--;fileSize -= file.size;if ( !fileCount ) {setState( 'pedding' );}removeFile( file );updateTotalProgress();};uploader.on( 'all', function( type ) {var stats;switch( type ) {case 'uploadFinished':setState( 'confirm' );break;case 'startUpload':setState( 'uploading' );break;case 'stopUpload':setState( 'paused' );break;}});uploader.onError = function( code ) {var msg;switch (code){case 'F_EXCEED_SIZE':msg = '上传错误,文件大小不得大于10M';break;case 'Q_EXCEED_NUM_LIMIT':msg = '最多可以上传1个文件';break;case 'Q_EXCEED_SIZE_LIMIT':msg = '上传文件大小过大';break;case 'Q_TYPE_DENIED':msg = '文件类型上传错误';break;case 'F_DUPLICATE':msg = '已经上传过该图片';break;}layer.alert(msg);};$upload.on('click', function() {if ( $(this).hasClass( 'disabled' ) ) {return false;}if ( state === 'ready' ) {uploader.upload();} else if ( state === 'paused' ) {uploader.upload();} else if ( state === 'uploading' ) {uploader.stop();}});$info.on( 'click', '.retry', function() {uploader.retry();} );$info.on( 'click', '.ignore', function() {alert( 'todo' );} );$upload.addClass( 'state-' + state );updateTotalProgress();//=============================================================================================================});function showBigImg(obj) {if (getExplorer == 'ie'){$('<div id="outerdiv2" style="position:fixed;top:0;left:0;background:rgba(0,0,0,0.7);z-index:99999;width:100%;height:100%;display:none;opacity: 1 !important;"><div id="innerdiv2" style="position:fixed;"><img id="bigimg" style="border:2px solid #fff;" src="" /></div></div>').appendTo(document.body);}else {$('<div id="outerdiv2" style="position:fixed;top:0;left:0;background:rgba(0,0,0,0.7);z-index:99999;width:100%;height:100%;display:none;"><div id="innerdiv2" style="position:fixed;"><img id="bigimg" style="border:2px solid #fff;" src="" /></div></div>').appendTo(document.body);}###这里是图片服务器 用于剪裁图片使用(阿里云图片文档有详细说明)var url = "http://ixxx.com/"+$("#licenseImgUrl").attr("data")+"?x-oss-process=image/resize,m_lfit,h_600";;$("#bigimg").attr("src",url);$("<img/>").attr("src",url).load(function () {var globalWidth = $(window).width();var globalHeight = $(window).height();var imgWidth = this.width;var imgHeight = this.height;var wid,hei,ratio=window.devicePixelRatio || 1;if (imgHeight > globalHeight * ratio){hei = globalHeight *ratio;wid = hei/imgHeight*imgWidth;if (wid > globalWidth*ratio){wid = globalWidth * ratio;}}else {if (imgWidth > globalWidth * ratio){wid = globalWidth * ratio;hei = wid/imgWidth*imgHeight;}else {wid = imgWidth;hei = imgHeight;}}$("#bigimg").css({"width":wid});var posiLeft,posiTop;if (imgWidth > imgHeight){posiLeft = (globalWidth-$("#bigimg").width())/2;posiTop = (globalHeight-imgHeight)/2;}else {posiLeft = (globalWidth-imgWidth)/2;posiTop = (globalHeight-imgHeight)/2;}if (getExplorer == 'ie'){$("#innerdiv2").css({top: "0px",left:Math.abs(posiLeft)-230,"opacity":"opacity: 1 !important"});}else {$("#innerdiv2").css({top:Math.abs(posiTop),left:Math.abs(posiLeft)});}$("#outerdiv2").fadeIn("fast");});$("#outerdiv2").click(function () {$(this).fadeOut("fast",function () {$(this).remove();});});}
</script>

后端代码

pom依赖

<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.8.0</version></dependency>

获取oss权限信息接口

@PostMapping("/getOssSign")@ResponseBodypublic String getSign(String type,String originName) throws UnsupportedEncodingException {Map<String,Object> map = new HashMap<>();String userName= UserUtils.getUser().getUserName();long expireTime = 30;long expireEndTime = System.currentTimeMillis() + expireTime * 100000;OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);Date expiration = new Date(expireEndTime);String dir = "";if (type.equals("4")){dir = profile.concat("/").concat("XXXXer/certification/").concat(userName).concat("/").concat(DateUtils.formatDate(new Date(),DateTimeUtils.YYYY_MM_DD)).concat("/");}else {dir = profile.concat("/").concat(userName).concat("/").concat(DateUtils.formatDate(new Date(),DateTimeUtils.YYYY_MM_DD)).concat("/");}PolicyConditions policyConds = new PolicyConditions();policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);byte[] binaryData = postPolicy.getBytes("utf-8");String encodedPolicy = BinaryUtil.toBase64String(binaryData);String postSignature = ossClient.calculatePostSignature(postPolicy);Map<String,Object> callbackMap = new HashMap<>();String guid = BusinessCodeGenUtil.INSTANCE.nextId();callbackMap.put("callbackUrl",callbackUrl);StringBuffer stringBuffer = new StringBuffer();Map<String,Object> customerParam = new HashMap<>();customerParam.put("x:guid", guid);customerParam.put("x:type",type);customerParam.put("x:originName",originName);stringBuffer.append("filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}&etag=${etag}&my_param="+JSONObject.toJSONString(customerParam));callbackMap.put("callbackBody",stringBuffer.toString());callbackMap.put("callbackBodyType","application/json");map.put("endpoint",endpoint);map.put("accessid",accessKeyId);map.put("policy",encodedPolicy);map.put("signature",postSignature);map.put("expire",String.valueOf(expireEndTime/1000));map.put("bucketName",bucketName);String encryptContent = JSONObject.toJSONString(callbackMap);map.put("callback", Base64Utils.encodeToString(encryptContent.getBytes("UTF-8")));//需处理map.put("dir",dir);map.put("guid",guid);String json= JSONObject.toJSONString(map);logger.info("callback:{}", json);return json;}

接受阿里云存储回调接口

   @PostMapping("/call")@ResponseBodypublic String callback(@RequestBody String data) throws IOException {logger.info("回调数据:"+data);fileService.saveUploadResult(data);return "SUCCESS";}
@Overridepublic void saveUploadResult(String ossCallbackBody) {ossCallbackBody=ossCallbackBody.replaceAll("\"","");/**解析json字符串**/Map<String,String> callbackBodyMap= JsonUtils.strToMap(ossCallbackBody);/**获取etag值**/String fileName=callbackBodyMap.get("filename");String etag=callbackBodyMap.get("etag");String size=callbackBodyMap.get("size");String myVar=callbackBodyMap.get("my_param");myVar=myVar.replaceAll("x\\:","");//        JsonObject jsonObject=JsonUtils.parseJson(myVar).getAsJsonObject();
//        Map<String,String> map=JsonUtils.strToMap(myVar);myVar=myVar.replaceAll("\\{","");myVar=myVar.replaceAll("\\}","");Map<String,String> map= JsonUtils.parseSpecialJson(myVar);String type=map.get("type");String guid=map.get("guid");String originName=map.get("originName");String objectName=fileName;String ossUrl= aliyunOSSUtil.getUrl(objectName);ossUrl= ossUrl.substring(0,ossUrl.indexOf("?"));FileHash fileHash=new FileHash();fileHash.setFileHashId(guid);fileHash.setRemark(etag);fileHash.setOssfilePath(ossUrl);fileHash.setTemfilePath(fileName);fileHash.setType(Integer.valueOf(type));fileHash.setFileSize(Integer.valueOf(size));fileHash.setFileName(originName);
//        fileHash.setFileName(fileName.substring(fileName.lastIndexOf("/")+1));fileHash.setStatus(CommonConstant.STATUS_SUCCESS);fileHashMapper.insertSelective(fileHash);}

相关js文件资源

https://gitee.com/pingfanrenbiji/mengfanxiao-resource/tree/master/static/common

封装直传阿里云存储文件上传控件相关推荐

  1. 教你三分钟上手阿里云OOS上传操作

    教你三分钟上手阿里云OOS上传操作 1.注册登录 如果小伙伴需要进行使用阿里云oss操作,第一步我们得注册/登录阿里云 https://www.aliyun.com/,小编建议大家尽量使用支付宝登录, ...

  2. springboot整合阿里云oss上传的方法示例

    这篇文章主要介绍了springboot整合阿里云oss上传的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 OSS申请和 ...

  3. spring boot 整合 阿里云oss上传

    Spring Boot 整合 阿里云OSS上传 OSS申请和配置 1. 注册登录 2.开通以及配置 springboot整合使用 1. 进入我们springboot的项目中,导入oss相关依赖 2. ...

  4. 阿里云Oss上传(Android版)

    写了个简单的阿里云Oss上传,封装成一个类,可以直接使用 首先在您的gradle中配置sdk: dependencies {compile 'com.aliyun.dpa:oss-android-sd ...

  5. Java实现阿里云OSS上传文件

    推荐:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.. 点击跳转到网站 1.准备工作:创建操作阿里云OSS许可证 阿里云官方文档 这里不再赘述,根据官方文档一步步的 ...

  6. Nginx 代理转发阿里云OSS上传的实现代码

    这篇文章主要介绍了Nginx 代理转发阿里云OSS上传的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 前言 因为小程序上传需要https,服务器https用的是 ...

  7. 阿里云文件上传工具类

    文件实体类 @Data public class UploadFile {private String fileName;private String fileType;private long fi ...

  8. SpringBoot整合阿里云OSS上传文件

    一.需求分析 文件上传是一个非常常见的功能,就是通过IO流将文件写到另外一个地方,这个地方可以是项目下的某个文件夹里,或者是本地电脑某个盘下面,还可以是云服务OSS里面,这里就是我要讲到的OSS,我写 ...

  9. thinkPHP 阿里云OSS 上传文件、直接下载

    阿里云OSS 上传文件.直接下载 1. 安装OSS SDK composer require aliyuncs/oss-sdk-php 2. thinkPHP接口 public function up ...

最新文章

  1. 用Genymotion来调试android应用
  2. linux 后台进程
  3. 一款N-沟道耗尽型JFET晶体管 MPF102
  4. 12张PPT看懂中国虚拟数字人产业现状:应用不止于虚拟偶像,2030年市场达2700亿|量子位智库(附下载)...
  5. containerd设置上网代理
  6. [开发技巧3]不显示报表直接打印
  7. django 与 vue 的完美结合
  8. 15 操作系统第四章 文件管理 文件的物理结构 文件存储空间管理
  9. 模拟京东按s键选中输入框
  10. matlab哪些教材好,新手入门,恳请推荐一本matlab好教材
  11. 【教学类-12-08】20221111《连连看竖版6*6 (3套题目空心图案(中班教学)》(中班主题《》)
  12. 使用rails Devise
  13. Exception】Chrome浏览器提示:此网页正试图从未经验证的来源加载脚本
  14. bde怎么配置oracle数据库,Oracle数据访问组件ODAC教程:如何从BDE和DOA迁移
  15. vscode 提示 vetur can‘t find `tsconfig.json`的解决办法
  16. window7激活方法
  17. jsp网页无法加载css解决方法
  18. 安卓多媒体应用-通知
  19. python可变数据类型和不可变数据类型_python 可变数据类型和不可变数据类型
  20. 04.南瓜树低代码平台平台 分析后的感想

热门文章

  1. java 中数组的创建 数组遍历 以及数组的输出(打印)
  2. mysql数据库druid密码加密_Druid数据库密码加密
  3. Maven史上最全总结
  4. ip申请 web应用_网络协议端口TCP/IP概览
  5. IOS 长按默认事件阻止 【坑】
  6. 【再探backbone 02】集合-Collection
  7. 写给90后快30岁的我们
  8. datapump跨平台升级迁移的总结
  9. Android(Fragment和Activity之间通信)
  10. 如何设置 jqplot 图表插件的轴和网格