Upload 上传

原生上传

原始的file控件显示效果比较差,而且不同浏览器显示结果不同,本框架借助CSS做了基本美化处理。基本做到了在chrome,Firefox,Opera,safafi浏览器中风格统一,但是在IE11和Edge中依然显示丑陋。以下演示三种状态,即常规,禁止(disabled)和只读(readonly)

选择文件:
禁止使用:
只读文件:
                                <div class="ax-form-group">
                                <div class="ax-flex-row">
                                <div class="ax-form-label">选择文件:</div>
                                <div class="ax-form-con">
                                <div class="ax-form-input">
                                <input type="file">
                                </div>
                                </div>
                                <a href="###" class="ax-form-head" style="background-image:url(
                                https://src.axui.cn/v2.0/examples/images/head01.jpg);"></a>
                                </div>
                                </div>

                                <div class="ax-break"></div>

                                <div class="ax-form-group">
                                <div class="ax-flex-row">
                                <div class="ax-form-label">禁止使用:</div>
                                <div class="ax-form-con">
                                <div class="ax-form-input">
                                <input type="file" disabled>
                                </div>
                                </div>
                                </div>
                                </div>

                                <div class="ax-break"></div>

                                <div class="ax-form-group">
                                <div class="ax-flex-row">
                                <div class="ax-form-label">只读文件:</div>
                                <div class="ax-form-con">
                                <div class="ax-form-input">
                                <input type="file" readonly>
                                </div>
                                </div>
                                </div>
                                </div>
                            

简介

文件上传控件用得比较频繁,但是兼容性和美观度却比较差,而且当前前端对于文件上传的要求已经变得很复杂,比如拖拽上传、多图上传、粘贴上传、上传预览等等。所以最终还是得用js插件来实现文件上传功能。

之前美化了dropzonejs用来作为文件上传组件,由于代码与AXUI不成体系,维护也不便。所以AXUI自行开发了专属的文件上传插件axUpload

特点

  • 1、支持单图上传和多图上传
  • 2、既可以自动上传也可以手动上传
  • 3、可以限制上传文件的数量
  • 4、可以限制单个文件的后缀类型和文件大小
  • 5、统计选择的文件数量和已上传的文件数量
  • 6、自动避免重复选择文件和重复上传文件
  • 7、支持删除前自定义dialog事件
  • 8、支持预览图片、音频和视频文件(H5格式)
  • 9、支持上传成功后下载文件
  • 10、支持四种列表风格,推荐使用gallery
  • 11、支持文件拖拽上传
  • 12、支持文件夹拖拽上传
  • 13、支持文件和文件夹混合拖拽上传
  • 14、支持粘贴文件上传(本地文件不允许)
  • 15、支持双重检测,即上传前js检测和上传完成后动态检测
  • 16、自定义文件类型图标

使用方法

插件运行方式有四种:

  • ax*属性:对type:file标签使用axUpload属性即可按默认参数运行插件。
  • ax*属性:对type:hidden标签使用axUpload属性,同时使用type属性(text/info/picture/gallery)可按默认参数运行插件。
  • ax*属性:对div标签使用axUpload属性即可按默认参数运行插件。
  • js实例:通过new axUpload('#ID')方式创建实例运行。

插件对原始file控件进行了一层封装,支持监听和回调。封装后文件域用ax-file类包裹;placeholder属性值等于输入提示文字,可为空;text等于按钮文字,可为空。右侧显示图片可配合ax-form-headax-form-img使用。

默认参数将仅仅是美化原file控件,适用于普通form提交。

选择文件:
选择文件:
  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">选择文件:</div>
                                                <div class="ax-form-con">
                                                <div class="ax-form-input">
                                                <input type="file" name="file01" axUpload>
                                                </div>
                                                </div>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">选择文件:</div>
                                                <div class="ax-form-con">
                                                <div class="ax-form-input">
                                                <input type="file" name="file02" id="file02">
                                                </div>
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             new axUpload('#file02');
                                            

回显图片

插件会自动检测选择的文件类型,如果检测到是图片类型,那么可以在网页某个地方回显。

对于type:beautify的上传控件,可自主配置beautify的参数:

  • placeholder: '请选择文件...', //美化input选择域提示文字
  • text: '选择文件', //美化input选择域的上传按钮文字
  • className:'ax-file',//美化input选择域的样式名
  • display:'',//选择的图片存放的预览位置(适合单个文件选择),#id、className、node均可
  • callback:'',//选择文件后的回调函数,支持参数files

注意callback的files参数是input选择域的原始文件,如果需要读取为base64格式的文件,请使用内置工具:this.readFile

单选文件:
多选文件:
  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">单选文件:</div>
                                                <div class="ax-form-con">
                                                <div class="ax-form-input">
                                                <input type="file" name="file03" id="file03">
                                                </div>
                                                </div>
                                                <a href="###" class="ax-form-head" id="file03img"><img src="dist/images/avatar.svg" /></a>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">多选文件:</div>
                                                <div class="ax-form-con">
                                                <div class="ax-form-input">
                                                <input type="file" name="file04" multiple id="file04">
                                                </div>
                                                <div id="file04img"></div>
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             new axUpload('#file03', {
                                                beautify: {
                                                display: '#file03img'
                                                }
                                                });
                                                let file04img = document.querySelector('#file04img');
                                                new axUpload('#file04', {
                                                beautify: {
                                                callback: function (files) {
                                                //files是从input读取的原始文件
                                                if ([...files].length > 0) {
                                                //先清空
                                                file04img.innerHTML = '';
                                                [...files].forEach(i => {
                                                //将文件转成base64的图片
                                                if (i.type.startsWith('image')) {
                                                //确保仅仅是图片类型
                                                this.readFile(i, (data) => {
                                                //axAddElem是AXUI的创建节点的工具函数
                                                file04img.appendChild(axAddElem('img', { src: data, width: 60 }));
                                                });
                                                }
                                                });
                                                }
    
                                                }
                                                }
                                                });
                                            

尺寸

同其他input和teatarea一样有4个尺寸可用,分别是ax-xs(高22px),ax-sm(高28px),ax-md(默认高38px),ax-lg(高48px)。

选择文件(xs):
选择文件(sm):
选择文件(md):
选择文件(lg):
                                <input type="file" class="ax-xs">
                                <div class="ax-break"></div>
                                <input type="file" class="ax-sm">
                                <div class="ax-break"></div>
                                <input type="file">
                                <div class="ax-break"></div>
                                <input type="file" class="ax-lg">
                                <div class="ax-break"></div>

                                <div class="ax-form-group ax-xs">
                                <div class="ax-flex-row">
                                <div class="ax-form-label">选择文件(xs):</div>
                                <div class="ax-form-con">
                                <div class="ax-form-input">
                                <input type="file" class="ax-xs" name="sizexs" axUpload>
                                </div>
                                </div>
                                </div>
                                </div>

                                <div class="ax-break"></div>

                                <div class="ax-form-group ax-sm">
                                <div class="ax-flex-row">
                                <div class="ax-form-label">选择文件(sm):</div>
                                <div class="ax-form-con">
                                <div class="ax-form-input">
                                <input type="file" class="ax-sm" name="sizesm" axUpload>
                                </div>
                                </div>
                                </div>
                                </div>

                                <div class="ax-break"></div>

                                <div class="ax-form-group">
                                <div class="ax-flex-row">
                                <div class="ax-form-label">选择文件(md):</div>
                                <div class="ax-form-con">
                                <div class="ax-form-input">
                                <input type="file" class="ax-md" name="sizemd" axUpload>
                                </div>
                                </div>
                                </div>
                                </div>

                                <div class="ax-break"></div>

                                <div class="ax-form-group ax-lg">
                                <div class="ax-flex-row">
                                <div class="ax-form-label">选择文件(lg):</div>
                                <div class="ax-form-con">
                                <div class="ax-form-input">
                                <input type="file" class="ax-lg" name="sizelg" axUpload>
                                </div>
                                </div>
                                </div>
                                </div>
                            

列表风格

以上讲述了type:beautify的使用方法,axUpload除此之外还支持四种列表展示方式。

  • type:text,简单的文件信息列表
  • type:info,文件详细列表,在text基础上增加了图片显示
  • type:picture,纯图片列表,适合上传图片
  • type:gallery,拖拽上传盒子,适合展示多媒体文件

本四种文件上传方式都是异步上传方式,必须填写type属性值和url属性值。

动态页面需要返回一个对象,格式如:{valid:'',message:'',url:'',name:'',time:''}。

  • valid,表示再次验证结果,布尔值,true或false
  • message,验证结果提示文字,字符串
  • url,文件上传成功后得到的真实文件路径,字符串
  • name,文件上传成功后得到的真实文件名,字符串
  • time,文件上传成功后得到时间戳,或者是原生文件的lastModified值
注意这四种显示方式是以隐藏域的方式接受实例值,如果是这四种类型,input的type类型不能是file。
text:
info:
picture:
gallery:
  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">text:</div>
                                                <div class="ax-col">
                                                <input type="hidden" axUpload='type:"text",url:"ajax/singleAjax.php"'>
                                                </div>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">info:</div>
                                                <div class="ax-col">
                                                <input type="hidden" axUpload='type:"info",url:"ajax/singleAjax.php"'>
                                                </div>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">picture:</div>
                                                <div class="ax-col">
                                                <input type="hidden" axUpload='type:"picture",url:"ajax/singleAjax.php"'>
                                                </div>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-form-label">gallery:</div>
                                                <div class="ax-col">
                                                <input type="hidden" axUpload='type:"gallery",url:"ajax/singleAjax.php"'>
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             <?php
                                                //定义上传目录
                                                $path = "filesDirectory/";
                                                //定义上传文件类型
                                                $extArr = array("jpg", "png", "gif", "txt", "doc", "docx", "pdf", "xsl", "xslx","mp3","mp4");
                                                //定义上传文件大小限制(1MB)
                                                $maxSize = 1024 * 1024 * 1024;
                                                //获取文件类型后缀
                                                function extend($file_name)
                                                {
                                                $extend = pathinfo($file_name);
                                                $extend = strtolower($extend["extension"]);
                                                return $extend;
                                                }
                                                //获得13位时间戳,与文件的lastModified位数保持一致
                                                function getTimestamp() {
                                                list($t1, $t2) = explode(' ', microtime());
                                                return (float)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
                                                }
                                                $timestamp = getTimestamp();
                                                //输出结果
                                                function echoResult($msg='上传出错了!',$time,$flag=false,$url='',$name='')
                                                {
                                                $object = array('valid' => $flag,'message' => $msg, 'url' => $url, 'name' => $name,'time'=>$time);
                                                $result = json_encode($object);
                                                echo $result;
                                                }
                                                if (isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST") {
                                                $file = $_FILES[array_shift(array_keys($_FILES))];
                                                $name = $file['name'];
                                                $size = $file['size'];
                                                $tmp = $file['tmp_name'];
                                                //随机文件名
                                                $ext = extend($name);
                                                $image_name = time() . rand(100, 999) . "." . $ext;
                                                //有必要在服务器端再做一次校验,避免绕开前端校验恶意上传攻击
                                                if (empty($name)) {
                                                echoResult('请选择文件!',$timestamp);
                                                exit;
                                                }
                                                if (!in_array($ext, $extArr)) {
                                                echoResult('文件格式不对!',$timestamp);
                                                exit;
                                                }
                                                if ($size > $maxSize) {
                                                echoResult('文件大小不能超过1MB',$timestamp);
                                                exit;
                                                }
                                                if(!file_exists($path)){
                                                //如果路径错误
                                                echoResult('模拟路径上传成功!',$timestamp,true,'examples/images/uploadtest.jpg',$image_name);
                                                exit;
                                                }else{
                                                //通过以上校验则上传文件返回文件路径{valid:true,message:'上传成功!',url:'files/xxx.jpg'}
                                                if (move_uploaded_file($tmp, $path . $image_name)) {
                                                $url = 'ajax/'.$path . $image_name;
                                                echoResult('上传成功!',$timestamp,true,$url,$image_name);
                                                exit;
                                                }
                                                }
    
                                                }
                                                ?>
                                            

手动上传

axUpload默认是选择文件后自动上传的,用户可通过设置action=manual参数并显示上传按钮实现手动上传。

动态页面需要返回一个对象,格式如:{valid:'',message:'',url:'',name:'',time:''}。

  • valid,表示再次验证结果,布尔值,true或false
  • message,验证结果提示文字,字符串
  • url,文件上传成功后得到的真实文件路径,字符串
  • name,文件上传成功后得到的真实文件名,字符串
  • time,文件上传成功后得到时间戳,或者是原生文件的lastModified值
  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" multiple axUpload='type:"gallery",url:"ajax/singleAjax.php",action:"manual",uploadBtn:{show:true}'>
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             同以上实例的php代码
                                            

所有功能

除了显示上传按钮手动上传之外,还可以显示清除按钮,显示上传提示和上传统计。

  • 显示清除按钮,对clearBtn使用show=true即可
  • 显示上传提示,对tipsShow=true即可显示上传提示,默认是显示的
    • size表示单个文件的大小限制,单位MB
    • min表示要求上传的最少文件数量
    • max表示允许上传的最多文件数量
    • accept表示允许上传的文件后缀,多个用英文逗号隔开
    • mime表示选择框中显示的文件类型,与H5中关于type=file中规定的accept参数一致
  • 显示上传统计,对summaryShow=true即可显示上传统计,插件将在上传后计算数值

动态页面需要返回一个对象,格式如:{valid:'',message:'',url:'',name:'',time:''}。

  • valid,表示再次验证结果,布尔值,true或false
  • message,验证结果提示文字,字符串
  • url,文件上传成功后得到的真实文件路径,字符串
  • name,文件上传成功后得到的真实文件名,字符串
  • time,文件上传成功后得到时间戳,或者是原生文件的lastModified值
  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" multiple axUpload='type:"text",url:"ajax/singleAjax.php",action:"manual",uploadBtn:{show:true},clearBtn:{show:true},max:6,size:1,summaryShow:true,accept:"jpg,gif,png,mp3,mp4"'>
                                                </div>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" multiple axUpload='type:"info",url:"ajax/singleAjax.php",action:"manual",uploadBtn:{show:true},clearBtn:{show:true},max:6,size:1,summaryShow:true,accept:"jpg,gif,png,mp3,mp4"'>
                                                </div>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" multiple axUpload='type:"picture",url:"ajax/singleAjax.php",action:"manual",uploadBtn:{show:true},clearBtn:{show:true},max:6,size:1,summaryShow:true,accept:"jpg,gif,png,mp3,mp4"'>
                                                </div>
                                                </div>
                                                </div>
    
                                                <div class="ax-break"></div>
    
                                                <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" multiple axUpload='type:"gallery",url:"ajax/singleAjax.php",action:"manual",uploadBtn:{show:true} ,clearBtn:{show:true},max:6,size:1,summaryShow:true,accept:"jpg,gif,png,mp3,mp4"'>
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             同以上实例的php代码
                                            

删除前确认

使用onBeforeRemoveonBeforeClear方法在删除文件之前再次确认,以避免误删。

  • onBeforeRemove支持参数obj,是一个对象,详细如下:
    • obj.dom,是当前存在列表中的待删除节点
    • obj.file,是待删除的文件(原生的)
    • obj.completed,布尔值,如果百分百上传成功则为true,没有该属性
    • obj.progress,是当前文件上传进度,完成前是uploading,完成后是uploaded
    • obj.state,是当前文件状态,是一个对象,比如:{valid:true,message:'上传成功!',url:'xxx/xxx.jpg',name:'xxx.jpg',time:1585203596}
  • onBeforeClear没有参数

onBeforeRemove可以使用内置方法:this.remove;onBeforeClear可以使用内置方法:this.clear

  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" multiple id="file11">
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             new axUpload('#file11', {
                                                type:'gallery',
                                                url:'ajax/singleAjax.php',
                                                action: 'manual',
                                                clearBtn: { show: true },
                                                uploadBtn: { show: true },
                                                onBeforeRemove: function (obj) {
                                                let _this = this;
                                                if (!obj.state.valid) {
                                                _this.remove(obj.file
                                                //,function(url, name, size){}
                                                );
                                                } else {
                                                new axDialog({
                                                content: '确定要删除该文件么?',
                                                confirm: {
                                                callback: function() {
                                                _this.remove(obj.file
                                                //,function(url, name, size){}
                                                );
                                                }
                                                }
                                                }).show();
                                                }
                                                },
                                                onBeforeClear: function() {
                                                let _this = this;
                                                new axDialog({
                                                content: '确定要清空所有文件么?',
                                                confirm: {
                                                callback: function() {
                                                _this.clear();
                                                }
                                                }
                                                }).show();
                                                }
                                                });
                                            
  •                                             同以上实例的php代码
                                            

上传前确认

使用onBeforeUpload可以在上传前再次校验,返回为true则上传,为false则停止上传。该方法支持一个参数,即待上传的文件。

一次只能上传一个有效文件!

  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" multiple id="file16">
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             new axUpload('#file16', {
                                                type: 'gallery',
                                                url: 'ajax/singleAjax.php',
                                                action: 'manual',
                                                clearBtn: { show: true },
                                                uploadBtn: { show: true },
                                                onBeforeUpload: function (obj) {
                                                if (obj.length >= 2) {
                                                new axMessage({
                                                content: '一次只能上传一个文件!',
                                                }).show();
                                                return false;
                                                } else {
                                                return true;
                                                }
                                                },
                                                });
                                            
  •                                             同以上实例的php代码
                                            

自定义文件图标

组件内置了三类图标,即image图片、video视频和audio音频,其他文件均是普通文件图标,用户可通过filetype参数自定义文件图标以获得良好的展示效果。

fileType参数将定义一个图标数组,他的值将类似:[{name:'',suffix:'',icon:''},...]

  • name,给图标类型取一个名字,比如'word'
  • suffix,文件后缀,比如'doc,docx'
  • icon,图标样式名称,比如'ax-iconfont ax-icon-heart'

上传个word看看!

  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" axUpload='type:"gallery",url:"ajax/singleAjax.php",fileType:[{name:"word",suffix:"doc,docx",icon:"ax-iconfont ax-icon-heart"}]'>
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             同以上实例的php代码
                                            

云直传

目前云服务比较流行,既能节省带宽又能节省存储空间,文件直接上云是很多项目团队的重要选择。

目前国内的主流对象存储服务商有阿里云、七牛云、腾讯云、又拍云等。由于本框架资源托管在又拍云,所以优先以又拍云为参照支持云上传功能。

上传逻辑过程如下:

  • 1、从服务商获得policy、signature和bucket
  • 2、ajax构造FormData上传
  • 3、成功返回url、size、msg、code等属性值
  • 4、根据返回值生成实例的value值
  • 5、通过allUploaded监听,将value值转成字符串发送后台上传数据库
  • 6、将value值转成字符串写入页面的隐藏域

云服务器直传需要配置cloud参数,该参数默认为空,即表示上传到本地服务器(url为本地链接)。我们以又拍云为例详细讲解cloud参数:

  • name:云存储服务器的名称,不填也没关系
  • field:云存储服务器获取上传文件的字段,通常为file,又拍云便是file
  • code:上传成功后的状态码,该属性用于区分校验状态,又拍云为200
  • server:服务器的网址,使用又拍云在成功后获得的url是一个相对路径,结合服务器网址才可预览或下载
  • append:是一个对象,是构造FormData需要追加的内容,使用又拍云必须配置policy和signature属性,例如append:{policy:'',signature:''},用户可根据云存储平台要求追加属性
  • keys:是一个对象,用于关联本组件和云存储平台的返回对象属性,又拍云成功返回的对象有file_size属性,该属性记录了文件的大小,那么我们需要通过keys:{size:'file_size'}进行对应关联。keys的属性有:name、url、size、message和time。需要注意的是如果云存储平台返回的是二维对象,比如{time:'',data:{url:'',size:''}},此时的url对应的key应该写作"data.url"
  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" id="file17">
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             new axUpload('#file17', {
                                                type: 'gallery',
                                                url: 'http://v0.api.upyun.com/axui-src',//从云服务平台获得
                                                action: 'manual',
                                                clearBtn: { show: true },
                                                uploadBtn: { show: true },
                                                cloud: {
                                                name: 'upcloud',//云存储表示,可不填
                                                code: 200,//又拍云返回200状态码表示成功
                                                server:'https://src.axui.cn/',//预览和下载时需要将网址拼接上
                                                //field:'file',//field不填将默认以file名上传文件
                                                append:{
                                                policy:'
                                                eyJidWNrZXQiOiJheHVpLXNyYyIsImV4cGlyYXRpb24iOjE3MTQyOTI2ODYsInNhdmUta2V5IjoiXC9maWxlc1wve3llYXJ9XC97bW9ufVwve3JhbmRvbX17LnN1ZmZpeH0iLCJhbGxvdy1maWxlLXR5cGUiOiJqcGcsanBlZyxnaWYscG5nLGRvYyxwZGYsbXAzLG1wNCJ9',
                                                signature:'
                                                3e72dd214f9e50d52c0b894b4409d2c8',
                                                },//每个云服务都至少需要策略和签名
                                                keys: {
                                                url: 'url',
                                                message: 'message',
                                                size: 'file_size',
                                                time: 'time',
                                                }//每个云服务上传后返回的对象属性不确定,但是本插件的创建value值的属性是确定的,通过keys进行关联
                                                }
                                                }).on('allUploaded', () => {
                                                console.log('上传完毕!')
                                                });
                                            
  •                                             <?php
                                                function upyunConfig ()
                                                {
                                                $bucket = 'xxxxxx';//定义bucket名
                                                $secret = 'xxxxxxxxxxx';//定义秘钥
                                                $options = array(
                                                'bucket' => $bucket, // 空间名
                                                'expiration' => time() + 600, // 授权过期时间
                                                'save-key' => '/files/{year}/{mon}/{random}{.suffix}',//存储路径规则
                                                'allow-file-type' => 'jpg,jpeg,gif,png,doc,pdf,mp3,mp4',//允许的文件格式
                                                );
                                                $policy = base64_encode(json_encode($options));//加密策略
                                                $signature = md5($policy.'&'.$secret); // MD5的操作员密码
                                                //返回对象
                                                return array(
                                                'signature' => $signature,
                                                'policy' => $policy,
                                                'bucket' => $bucket,
                                                );
                                                }
                                                $upyunConfig = upyunConfig();
                                                ?>
                                            

初始化列表

文件上传完毕需要在下一次打开页面的时候显示文件列表,此时需要使用实例show方法。使用show方法需要传入url值,可以通过三种方式传入:

  • 字符串,多个url用英文逗号隔开,例如'url1,url2,url3'
  • 字符串数组,例如['url1','url2,'url3']
  • 对象数组,例如[{name:'',url:'',time:''},...]
    • url,文件地址,必填
    • name,文件名,选填
    • time,文件时间戳,选填

show方法是将现有的图片再次转成二进制文件,依照组件内部流程显示在列表中并标识为uploadedcompleted状态,不会再重新上传,但是可以删除。

uploaded表示已经成功上传,返回成功状态;completed表示已经完全从本地上传,但是返回可能成功或失败。

  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" id="file13">
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             let images = [
                                                {name:'china01',url:'examples/images/china01.jpg'},
                                                {name:'china02',url:'examples/images/china02.jpg'},
                                                {name:'china03',url:'examples/images/china03.jpg'}
                                                ]
                                                new axUpload('#file13', {
                                                type:'gallery',
                                                url:'ajax/singleAjax.php',
                                                action: 'manual',
                                                clearBtn: { show: true },
                                                uploadBtn: { show: true }
                                                }).show(images);
                                            
  •                                             同以上实例的php代码
                                            

操作方法

axUpload插件有系列内部成员变量和内部操作方法,用户根据这些变量和方法可以自由操作实例,并且方便与服务器数据库进行交互。

请使用f12打开浏览器控制台来观摩以下实例。

  • 内部成员变量:
    • this.value:输出当前实例的值,格式如:[{name:'',url:'',size:'',time:''}],上传成功的文件才有url值。
    • this.inputValue:根据this.value转成url字符串,默认以英文逗号分割,分隔符可以通过options.separator来自定义。
    • this.history:输出当前列表中的file文件,包括校验成功和失败的文件
    • this.files:输出当前列表中校验成功的file文件
    • this.details:输出当前列表中的所有文件详细,即在this.history基础上追加了校验、dom节点和进行过程,格式如:[{file:'',dom:'',completed:'',progress:'',state:{valid:'',message:'',url:'',name:'',time:''}},...]
  • 内部操作方法:
    • this.show(obj):初始化列表,该方法在上述实例中已经讲述
    • this.remove(file,callback):参数为文件和回调函数,参数说明如下:
      • file:文件类型,从this.history取得的文件
      • callback:函数类型,删除节点后的回调函数,有三个参数:url路径地址,name文件名,size文件体积
    • this.clear(callback):清空列表,参数说明如下:
      • callback:函数类型,清空后的回调函数,无参数
    • this.renderList(files, callback):往实例列表添加文件,支持两个参数:
      • files:原生文件数组,如果是其他数据格式请先转成原生files
      • callback:函数类型,添加后回调,无参数
    • this.upload(callback):向后台上传文件,支持回调函数,无参数,注意上传不等于完成
    • this.getSummary():获得列表的统计信息,无参数,返回统计信息字符串
    • this.getUploadingFiles():获得待上传的文件,无参数,返回this.details中待上传的项
    • this.getSuffix(file):获得文件的后缀,支持file参数,该参数是原生file文件
    • this.readFile(file, callback):读取文件信息并转成base64格式,支持两个参数:
      • file:文件类型,从this.history取得的文件
      • callback:函数类型,读取文件后的操作(异步),有一个参数:data,即base64文件字符串
    • this.fileValid(file):对文件进行校验,返回对象:{ valid: '', message: '' },参数file为原生文件
    • this.globalValid():对列表进行全局校验,返回对象:{ valid: '', message: '' },无参数
    • this.getUrlFile(url, fileName, callback):将链接文件转成原生file文件(异步),支持三个参数:
      • url:文件地址,可以是相对路径也可以是绝对路径,但是如果是非同域地址则需要文件所在服务器开放使用权限
      • fileName:创建文件后给文件取名
      • callback:创建文件后的回调函数,支持一个参数:file,即创建好的原生文件
  •                                             <input type="hidden" id="file15">
                                                <div class="ax-break"></div>
                                                <button class="ax-btn" id="addFiles">添加两个新文件</button>
                                                <button class="ax-btn" id="uploadFiles">上传文件</button>
                                                <button class="ax-btn" id="removeFile">删除第一个文件</button>
                                                <button class="ax-btn" id="getDetails">获取this.details</button>
                                                <button class="ax-btn" id="getInfo">获得统计信息</button>
                                                <button class="ax-btn" id="clearFiles">清空文件列表</button>
                                                <div class="ax-break"></div>
                                                <button class="ax-btn" id="getValue">上传后获取this.value</button>
                                                <button class="ax-btn" id="getInputValue">上传后获取this.inputValue</button>
                                            
  •                                             let methodIns = new axUpload('#file15', {
                                                type: 'gallery',
                                                url: 'ajax/singleAjax.php',
                                                action: 'manual',
                                                clearBtn: { show: true },
                                                uploadBtn: { show: true },
                                                onRemove: function () {
                                                console.log('当前文件列表详细是:');
                                                console.log(this.details);
                                                },
                                                onUploaded: function () {
                                                console.log('当前输出值是:');
                                                console.log(this.value);
                                                }
                                                }),
                                                getValue = document.querySelector('#getValue'),
                                                getInputValue = document.querySelector('#getInputValue'),
                                                getDetails = document.querySelector('#getDetails'),
                                                addFiles = document.querySelector('#addFiles'),
                                                removeFile = document.querySelector('#removeFile'),
                                                uploadFiles = document.querySelector('#uploadFiles'),
                                                clearFiles = document.querySelector('#clearFiles'),
                                                getInfo = document.querySelector('#getInfo');
                                                getValue.onclick = () => {
                                                console.log('当前输出值是:');
                                                console.log(methodIns.value);
                                                }
                                                getDetails.onclick = () => {
                                                console.log('当前文件列表详细是:');
                                                console.log(methodIns.details);
                                                }
                                                getInputValue.onclick = () => {
                                                console.log('当前输出到隐藏域的值是:' + methodIns.inputValue);
                                                }
                                                addFiles.onclick = () => {
                                                let urls = [
                                                {
                                                name: 'china01.jpg',
                                                url: 'examples/images/china01.jpg'
                                                },
                                                {
                                                name: 'china02.jpg',
                                                url: 'examples/images/china02.jpg'
                                                }]
                                                urls.forEach(i => {
                                                //getUrlFile是异步的
                                                methodIns.getUrlFile(i.url, i.name, (file) => {
                                                //renderList的第一个参数需要是数组
                                                methodIns.renderList([file], () => {
                                                console.log('更新了列表,等待上传!');
                                                });
                                                });
                                                });
                                                }
                                                uploadFiles.onclick = () => {
                                                methodIns.upload(() => {
                                                console.log('文件上传了!');
                                                });
                                                }
                                                removeFile.onclick = () => {
                                                if(methodIns.history.length == 0){
                                                return false;
                                                }
                                                methodIns.remove(methodIns.history[0], () => {
                                                console.log('删除了第一个文件!');
                                                });
                                                }
                                                clearFiles.onclick = () => {
                                                methodIns.clear(()=>{
                                                console.log('删除了所有文件!');
                                                });
                                                }
                                                getInfo.onclick = () => {
                                                console.log(methodIns.getSummary());
                                                }
                                            
  •                                             同以上实例的php代码
                                            

监听事件

本插件有若干监听方法,以on为关键字,实例后监听和在参数中监听效果相同。格式是:instance.on('event',function(){});具体事件说明如下:

  • onRemove/remove 删除文件后执行,支持三个参数:url文件路径, name文件名, size文件体积
  • onClear/clear 列表清空后执行后执行,无参数
  • onUploaded/uploaded 文件上传后执行,支持参数extract即该文件详细和raw即后台返回的原始数据,返回成功才会执行该监听事件
  • onAllUploaded/allUploaded 所有有效文件都上传后执行,支持参数raw即后台返回的原始数据,返回成功才会执行该监听事件
  • onError/error 文件上传报错后执行,支持参数extract即该文件详细和raw即后台返回的原始数据
  • onCompelted/completed 文件100%上传后执行,支持参数obj即该文件详细,注意即使返回错误也可以执行该监听事件
  • onAllCompleted/allCompleted 所有有效文件100%上传后执行,无参数,注意即使返回错误也可以执行该监听事件
  • onUploading/uploading 文件列表开始上传执行,无参数
  • onRendered/rendered 文件DOM节点渲染完成执行,支持参数obj,即该文件详细
  • onChanged/changed input选择域值改变后执行,支持参数files,即input选择域的files值
  • onPasted/pasted 对上传区域使用粘贴后执行,支持参数file,即剪切板的文件
  • onDropped/dropped 拖放上传区域后执行,支持参数files,即拖来的文件

演示实例显示结果使用了console.log方法,请按下F12按键打开开发者工具中的“控制台”查看监听效果。

  •                                             <div class="ax-form-group">
                                                <div class="ax-flex-row">
                                                <div class="ax-col">
                                                <input type="hidden" id="file14">
                                                </div>
                                                </div>
                                                </div>
                                            
  •                                             let onIns = new axUpload('#file14', {
                                                type: 'gallery',
                                                url: 'ajax/singleAjax.php',
                                                action: 'manual',
                                                clearBtn: { show: true },
                                                uploadBtn: { show: true }
                                                });
                                                onIns.on('remove', function (url, name, size) {
                                                console.log(`remove:删除的文件是${name},体积${size},路径${url}`);
                                                }).on('clear', function () {
                                                console.log(`clear:全部清空了!`);
                                                }).on('uploaded', function (obj) {
                                                console.log(`uploaded:文件成功上传了,路径${obj.state.url}`);
                                                }).on('completed', function (obj) {
                                                console.log(`completed:文件100%上传了!`);
                                                }).on('allUploaded', function () {
                                                console.log(`allUploaded:所有文件全部成功上传了`);
                                                }).on('allCompleted', function (obj) {
                                                console.log(`allCompleted:所有文件100%上传了`);
                                                }).on('error', function (obj) {
                                                console.log(`error:上传报错:${obj.state.message},文件是:${obj.file.name}`);
                                                }).on('uploading', function () {
                                                console.log(`uploading:文件开始上传了`);
                                                }).on('rendered', function (obj) {
                                                console.log(`rendered:已经生成了节点,文件是${obj.file.name}`);
                                                }).on('changed', function (files) {
                                                console.log(`changed:input值发生了变化,文件是如下:`);
                                                console.log(files);
                                                }).on('pasted', function (file) {
                                                console.log(`pasted:文件粘贴进来了,文件是如下:`);
                                                console.log(file);
                                                }).on('dropped', function (files) {
                                                console.log(`dropped:文件拖进来了,文件是如下:`);
                                                console.log(files);
                                                });
                                            
  •                                             同以上实例的php代码
                                            

参数选项

                                document.addEventListener("DOMContentLoaded", function() {
                                var demo1 = new axUpload('#id',{
                                    insName: '',//实例名称,字符串格式;如果填写了实例名称,那么该实例会被添加到实例合集当中,通过axInstance方法可获取本实例,详细请查看:ax-utils-instance.php
                                    type: 'beautify', //文件回显方式,beautify原始文件域,text普通文件列表,info信息列表,pictrue图片列表,gallery多图画廊
                                    accept: 'jpg,jpeg,gif,png,svg,doc,docx,xls,xlsx,txt,mp4,mp3,pdf', //支持的文件类型(后缀),多个用英文逗号隔开
                                    mime: '',//打开窗口后所能显示的文件类型,比如填"image/*"在窗口只会显示图片类型的文件
                                    multiple: true, //是否支持多选,默认true支持,可选择false仅单选
                                    name: '', //隐藏的input控件的name
                                    separator: ',',//填入input隐藏域值的分割符,默认是英文逗号
                                    columns: 0,//在gallery模式下设定列数,默认为0表示不设置
                                    min: 0, //至少上传多少个文件,0表示不限制
                                    max: 0, //最多能上传多少个文件,0表示不限制
                                    size: 0, //尺寸,单位MB,0表示不限制
                                    url: '', //提交的动态页面地址
                                    fileType: [], //文件对象的图标样式,[{name:'',suffix:'',icon:''}]
                                    action: 'auto', //选好文件后的提交方式,默认是auto选好之后就自动上传,可选择manual手动点击某按钮上传
                                    tipsShow: true, //是否显示上传要求文字信息,默认true显示,可选择false不显示
                                    summaryShow: false,//是否显示上传的统计信息,默认fale不显示,可选择true显示
                                    cloud: '',//是否直传到对象存储服务器,默认为空即上传到本地服务器,目前可填upcloud,其他云平台用户自行扩展,
                                    //cloud:{name:'upcloud',field:'file',code:200,server:'https://src.axui.cn/',append:{policy:'',signature:''},keys:{name:'',url:'url',size:'file_size',time:'time'}}
                                    pastable: {
                                        before: '请点击使用ctrl+v粘贴上传',
                                        ing: '使用ctrl+v粘贴进来',
                                        after: 'ctrl+v粘贴上传成功',
                                    },//是否允许粘贴上传,默认允许,如果需要禁止,可以让该参数为空或者为false
                                    icons: {
                                        file: 'ax-iconfont ax-icon-file-text',//默认文件图标
                                        attach: 'ax-iconfont ax-icon-attach',//默认附件图标
                                        image: 'ax-iconfont ax-icon-image',//图片图标
                                        video: 'ax-iconfont ax-icon-video',//视频图标
                                        audio: 'ax-iconfont ax-icon-music'//音频图标
                                    },//常用图标
                                    beautify: {
                                        placeholder: '请选择文件...', //美化file的input提示文字
                                        text: '选择文件', //美化file的上传按钮文字
                                        className: 'ax-file',//美化file的样式名
                                        display: '',//选择的图片存放的预览位置(适合单个文件选择),#id、className、node均可
                                        callback: '',//选择文件后的回调函数,支持参数files
                                    },
                                    message: {
                                        passed: '通过文件校验!',
                                        exceeded: '超过了文件数量限制!',
                                        tooLarge: '文件体积太大了!',
                                        errorSuffix: '不支持该文件格式!',
                                        success: '上传成功!',
                                        failed: '提交地址可能错误!',
                                    },//定义实例中的提示文字
                                    chooseBtn: {
                                        icon: '<i class="ax-iconfont ax-icon-plus"></i>',
                                        text: '选择文件',
                                        className: '',
                                        props: {},
                                        show: true,
                                    },//定义选择文件按钮属性
                                    uploadBtn: {
                                        icon: '<i class="ax-iconfont ax-icon-upload"></i>',
                                        text: '立即上传',
                                        className: '',
                                        props: {},
                                        show: false,
                                    },//定义上传文件按钮属性
                                    clearBtn: {
                                        icon: '<i class="ax-iconfont ax-icon-trash"></i>',
                                        text: '删除全部',
                                        className: '',
                                        props: {},
                                        show: false,
                                    },//定义清除文件按钮属性
                                    cubeBtn: {
                                        icon: '<i class="ax-iconfont ax-icon-plus-t"></i>',
                                        text: '',
                                        className: '',
                                        props: {},
                                        show: true,
                                    },//定义picture添加文件按钮属性
                                    boxBtn: {
                                        icon: '<i class="ax-iconfont ax-icon-addpic"></i>',
                                        text: '点击或拖拽上传',
                                        className: '',
                                        props: {},
                                        show: true,
                                    },//定义gallery选择文件按钮属性
                                    breakpoints: {},//使用断点以适配终端,详情查看ax-utils-other.php页面
                                    onRendered:'',//文件DOM节点渲染完成执行,支持参数obj,即该文件详细
                                    onPasted:'',// 对上传区域使用粘贴后执行,支持参数file,即剪切板的文件
                                    onDropped:'',// 拖放上传区域后执行,支持参数files,即拖来的文件
                                    onUploading: '', //文件列表开始上传执行,无参数
                                    onUploaded: '', //上传成功后的回调函数,支持参数extract(当前文件详细{file:'',dom:'',state:''})和支持参数raw即后台返回的原始数据
                                    onAllUploaded: '', //所有有效文件都上传后执行,支持参数extract(当前文件详细{file:'',dom:'',state:''})和支持参数raw即后台返回的原始数据
                                    onCompleted: '', //文件100%上传后执行,支持参数obj,即该文件详细,注意即使返回错误也可以执行该监听事件
                                    onAllCompleted: '', //所有有效文件100%上传后执行,无参数,注意即使返回错误也可以执行该监听事件
                                    onError: '', //发生错误时回调函数,支持参数extract(当前文件详细{file:'',dom:'',state:''})和支持参数raw即后台返回的原始数据
                                    onChanged: '', //文件改变时的回调函数,支持参数files(所有通过校验的文件)
                                    onRemove: '', //文件删除后的回调函数,支持参数file(当前删除的文件)
                                    onClear: '', //文件全部清空时的回调函数,支持参数files(所有通过校验的文件)
                                    onBeforeRemove: '', //文件删除前的回调函数,支持参数obj(当前删除的文件详细{file:'',dom:'',state:''})
                                    onBeforeClear: '', //文件清空前的回调函数,无参数
                                    onBeforeUpload: '',//上传前确认是否上传,如果返回true则上传,如果返回false则停止上传,支持参数files(所有通过校验待上传的文件)
                                });
                                });
                            
以axMenu插件为例,如果在元素上通过ax*使用属性,需要使用类似json的写法,属性不需要使用引号,如果值是字符串需要使用引号包裹,如果值是数字、布尔值、null或undefined不需要引号;比如要设置active,那么在元素的ax*属性中应该这样书写:axMenu="active:2"