效果如下:
图片验证签名验证信息 url如下:图片验证信息与后端同学进行对接,可通过接口或url传递到前端。
http://192.168.1.9:8083?limit=5&label=‘xxx’&OSSAccessKeyId=LTAIpX3MEAfuMYiq&policy=eyJleHBpcmF0aW9uIjoiMjAxOC0wNy0wNlQwOToyNToxNVoiLCJjb25kaXRpb25zIjpbWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsMCwxMDQ4NTc2MDAwXSxbInN0YXJ0cy13aXRoIiwiJGtleSIsImltYWdlXC9wcmVzaWduZWRcL2NlcnRcLyJdXX0=&signature=UDWBhlwrYQrVt7rC3r5OXDcd/gs=&dir=image/presigned/cert/&host=http://xxxxxx.com&_t=1530840135305
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>上传图片</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta content="telephone=no,email=no" name=format-detection />
<meta name="renderer" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="renderer" content="webkit|ie-comp|ie-stand" />
<!--<script src="/js/vue.min.js"></script>
<script src="/js/jquery.min.js"></script>
<script src="/js/plupload-3.1.2/plupload.full.min.js"></script>-->
<!-- cdn -->
<script src="http://vuejs.org/js/vue.min.js"></script>
<script src="http://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/plupload/3.1.2/plupload.full.min.js"></script>
<style>
/* 去除浏览器默认样式reset */
html, body, body div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, figure, footer, header, menu, nav, section, time, mark, audio, video, details, summary {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font-weight: normal;
vertical-align: baseline;
background: transparent;
-webkit-tap-highlight-color:rgba(255,255,255,0);
}
html, body {
width: 100%;
height: 100%;
font-size: 0.28rem;
}
main, article, aside, figure, footer, header, nav, section, details, summary {display: block;}
ul {list-style: none;}
table {border-collapse: separate; border-spacing: 0;}
th {font-weight: bold; vertical-align: bottom;}
td {font-weight: normal; vertical-align: top;}
input{
outline: none;
border: none;
}
/* 页面样式 */
.cf {
zoom: 1;
}
.cf:after {
content: "";
display: table;
clear: both;
}
.fl{
float: left;
}
#app{
width: 100%;
height: 100%;
}
.logo{
height: 2rem;
display: flex;
align-items: center;
justify-content: center;
}
.logoImg{
width: 1.6rem;
height: 1.6rem;
}
.imgContent{
margin-top: 0.2rem;
}
.imgContent p{
font-size:0.26rem;
color: #000000;
text-align: center;
}
.imgBody{
margin-top: 0.4rem;
}
.imgCenter{
margin: 0 auto;
width: 6.6rem;
}
.pic-item {
position:relative;
width: 1.8rem;
height: 1.8rem;
margin:0 .4rem .4rem 0;
}
.pic-item img {
width: 100%;
height: 100%;
}
.delete-pic{
position:absolute;
top:-.15rem;
right:-.15rem;
border: 1px solid red;
border-radius: 50%;
z-index:1;
width:.38rem;
height:.38rem;
text-align: center;
line-height:.38rem;
}
.icon{
font-size:.12rem;
color:red;
display:inline-block;
}
.onloadContent{
width: 100%;
height: 2rem;
text-align: center;
line-height: 2rem;
bottom: 0;
left: 0;
}
.selectFile{
width: 1.6rem;
height: 1.6rem;
line-height: 1.6rem;
text-align: center;
display: inline-block;
background-color: #c6ae6c;
border-radius: 50%;
color: #ffffff;
margin-right: 0.2rem;
}
.selectFile p{
display: inline-block;
width: 0.6rem;
font-size: 0.24rem;
line-height: 0.4rem;
vertical-align: middle;
}
.confirmLoad{
width: 1.6rem;
height: 1.6rem;
line-height: 1.6rem;
text-align: center;
display: inline-block;
background-color: black;
border-radius: 50%;
color: #ffffff;
}
.confirmLoad p{
display: inline-block;
width: 0.6rem;
font-size: 0.24rem;
line-height: 0.4rem;
vertical-align: middle;
}
/* 蒙版 */
.appMask{
width: 100%;
height: 100%;
z-index: 10;
top: 0;
position: fixed;
background-color: rgba(0, 0, 0, 0.3)
}
/* 图片弹出框 */
.imgPop{
width: 6rem;
height: 8rem;
background-color: red;
position: fixed;
z-index: 20;
top: 12%;
left: 50%;
transform: translateX(-50%);
}
.popImg{
width: 100%;
height: 100%;
}
.popClose{
position:absolute;
top:-.15rem;
right:-.15rem;
border: 1px solid red;
border-radius: 50%;
z-index:21;
width:.38rem;
height:.38rem;
text-align: center;
line-height:.38rem;
}
</style>
</head>
<body>
<div id="app">
<div class="logo">
<img class="logoImg" src="" alt="">
</div>
<div class="imgContent">
<p>请选择{{label}}或拍照上传</p>
<p>最多不超过{{limit}}张图片</p>
<div class="imgBody">
<div class="imgCenter cf">
<div class="pic-item fl" v-for="(imgsrc,index) in images" :key="index" @click="showPop(imgsrc)">
<img :src="imgsrc" alt="">
<span class="delete-pic" @click.stop="removeSelectImage(index)">
<i class="icon">X</i>
</span>
</div>
</div>
</div>
</div>
<div class="onloadContent">
<input type="button" id="selectBtn" class='btn selectFile' value="选择上传" />
<input type="button" @click="uplaod" class='btn confirmLoad' value="确认上传" />
</div>
<!-- 蒙版 -->
<div class="appMask" v-show="popStatus"></div>
<!-- 弹出层 -->
<div class="imgPop" v-show="popStatus">
<img class="popImg" :src=currentImg alt="">
<span class="popClose" @click="closePop">
<i class="icon">X</i>
</span>
</div>
</div>
<script>
// 引入rem,使用rem单位,对不同手机屏幕进行适配
(function (doc, win) {
var docEl = doc.documentElement
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
var recalc = function () {
var clientWidth = docEl.clientWidth
if (!clientWidth) return
if (clientWidth >= 750) {
docEl.style.fontSize = '100px' // 1rem = 100px
} else {
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'
}
}
if (!doc.addEventListener) return
win.addEventListener(resizeEvt, recalc, false)
doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window)
// 截取url指定参数
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null) return decodeURIComponent(r[2]);
return null; //返回参数值
}
var vapp = new Vue({
el : '#app',
data : {
ossSignature : {OSSAccessKeyId:"",policy:"",signature:"",dir:'',host:'',success_action_status:'0',key:""},
limit : 1,
label : '',
images:[],
postImages:[],
uploader : null,
popStatus: false, //是否显示蒙版和图片弹出框
currentImg:'' // 点开大图的当前图片
},
created : function(){
console.log('created');
this.ossSignature.OSSAccessKeyId = getUrlParam('OSSAccessKeyId');
this.ossSignature.policy = getUrlParam('policy');
this.ossSignature.signature = getUrlParam('signature');
this.ossSignature.host = getUrlParam('host');
this.ossSignature.dir = getUrlParam('dir');
this.ossSignature.success_action_status = '200';
this.ossSignature.key = '';
this.limit = getUrlParam('limit');
this.existed = getUrlParam('existed');
this.label = getUrlParam('label');
document.title = this.label;
},
mounted: function(){
var self = this;
this.uploader = new plupload.Uploader({
runtimes : 'html5,gears,browserplus,silverlight,flash,html4',
browse_button : 'selectBtn',
container: document.getElementById('app'),
url : this.ossSignature.host, //服务器端的上传页面地址
flash_swf_url : 'lib/plupload-2.1.2/js/Moxie.swf',
silverlight_xap_url : 'lib/plupload-2.1.2/js/Moxie.xap',
filters: {
mime_types : [ //只允许上传图片和zip,rar文件
{ title : "Image files", extensions : "jpg,png,bmp,jpeg" }
],
max_file_size : '10mb', //最大只能上传10mb的文件
prevent_duplicates : true //不允许选取重复文件
},
init : {
FilesAdded: function(up, files) {
var oldLen = up.files.length - files.length;
up.files.splice(self.limit, up.files.length);
files = files.slice(0, self.limit - oldLen);
files = files || [];
plupload.each(files, function(file) {
console.log(file);
if (!file || !/image\//.test(file.type)) return; //确保文件是图片
var fr = new plupload.FileReader();
fr.onload = function () {
file.imgsrc = fr.result;
self.images.push(fr.result);
//fr.destroy();
fr = null;
}
fr.readAsDataURL(file.getSource());
});
},
BeforeUpload:function(up, file){
var fileName = file.name;
var suffix = fileName.split('.').pop();
fileName = self.random_string() + '.'+suffix;
self.ossSignature.key = self.ossSignature.dir + fileName;
file.remotePath = self.ossSignature.key;
},
FileUploaded: function(up, file, info) {
if (info.status == 200){
console.log(file.remotePath);
}
},
UploadComplete : function(uploader){
let len = uploader.files.length;
for (var i=0;i<len;i++){
self.postImages.push(self.ossSignature.host+'/'+uploader.files[i].remotePath);
}
self.postImages.splice(self.limit,uploader.files.length)
$.ajax({
type : 'post',
url: '/upload/image/set',
data : {signature:self.ossSignature.signature,images:self.postImages},
dataType: 'json',
success: function (data) {
alert('上传成功');
}
});
}
}
});
this.uploader.init();
},
methods : {
selectImage: function(file, fileList){
for (var i=0;i<fileList.length;i++){
this.images.push(fileList[i].url);
}
},
removeSelectImage : function(index){
this.images.splice(index,1);
console.log(JSON.stringify(this.uploader.files));
this.uploader.files.splice(index,1);
console.log(JSON.stringify(this.uploader.files));
},
random_string : function(len){
len = len || 32;
let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
let maxPos = chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
},
uplaod : function(){
if (this.images.length<=0){
alert('请选择要上传的照片');
return
}
this.uploader.setOption({
'url': this.ossSignature.host,
'multipart_params': this.ossSignature
});
this.uploader.start();
},
// 显示蒙版和弹出框
showPop (imgsrc){
this.currentImg = imgsrc
this.popStatus = true
},
// 关闭蒙版和弹出框
closePop (){
this.popStatus = false
}
}
});
</script>
</body>
</html>