搜索组件模块
grid 栅格布局
layout admin 布局
color 颜色
iconfont 字体图标
font 字体大小 颜色
animation 动画
button 按钮
form 表单组
input 输入框
select 下拉选择框
checkbox 复选框
switch 开关
radio 单选框
textarea 文本域
nav 导航菜单
menu 基础通用菜单
breadcrumb 面包屑
tabs 选项卡
progress 进度条
panel 面板 / card
collapse 折叠面板/手风琴
table 表格元素
badge 徽章
timeline 时间线
blockquote 引用块
fieldset 字段集
hr 分割线
layer 弹出层/弹窗综合
laydate 日期时间选择器
laypage 分页
laytpl 模板引擎
table 数据表格
form 表单模块
upload 文件/图片上传
dropdown 下拉菜单
contextmenu 右键菜单
transfer 穿梭框
tree 树形菜单
colorpicker 颜色选择器
element 常用元素操作
slider 滑块
rate 评分
carousel 轮播/跑马灯
layedit 富文本编辑器
flow 信息流/图片懒加载
util 工具集
code 代码文本行修饰
layim
layuiadmin
-

图片/文件上传 - layui.upload

上传模块自 layui 2.0 的版本开始,进行了全面重写,这使得它不再那么单一,它所包含的不仅是更为强劲的功能,还有灵活的 UI。任何元素都可以作为上传组件来调用,譬如按钮、图片、普通的 DIV 等等,而不再是一个单调的 file 文件域。

模块加载名称:upload

快速使用

一切从小试牛刀开始。通常情况下,我们上传文件是借助 type="file" 的 input 标签来完成的,但非常遗憾的是,它不能很好地与其它表单元素并存,所以我们常常要单独为它做一个业务层面的“异步上传”,即先让图片上传,再和其它表单一起提交保存。下面是一个小示例:

这原本只是一个普通的 button,正是 upload 模块赋予了它“文件选择”的特殊技能。当然,你还可以随意定制它的样式,而不是只局限于按钮。

对应的代码code

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>upload模块快速使用</title>
  6. <link rel="stylesheet" href="/static/build/layui.css" media="all">
  7. </head>
  8. <body>
  9. <button type="button" class="layui-btn" id="test1">
  10. <i class="layui-icon">&#xe67c;</i>上传图片
  11. </button>
  12. <script src="/static/build/layui.js"></script>
  13. <script>
  14. layui.use('upload', function(){
  15. var upload = layui.upload;
  16. //执行实例
  17. var uploadInst = upload.render({
  18. elem: '#test1' //绑定元素
  19. ,url: '/upload/' //上传接口
  20. ,done: function(res){
  21. //上传完毕回调
  22. }
  23. ,error: function(){
  24. //请求异常回调
  25. }
  26. });
  27. });
  28. </script>
  29. </body>
  30. </html>

一切看起来是那样的简单,乃至于我不得不凑一段文字来填充这一行的版面。这样好像与下文衔接起来会比较谐调的样子(自我感觉)

核心方法与基础参数选项

使用 upload 模块必须与 upload.render(options) 方法打交道,其中的 options即为基础参数,它是一个对象。

</>code

  1. var upload = layui.upload; //得到 upload 对象
  2. //创建一个上传组件
  3. upload.render({
  4. elem: '#id'
  5. ,url: ''
  6. ,done: function(res, index, upload){ //上传后的回调
  7. }
  8. //,accept: 'file' //允许上传的文件类型
  9. //,size: 50 //最大允许上传的文件大小
  10. //,……
  11. })

从 layui 2.1.0 开始,允许你直接在元素上设定基础参数,如:

</>code

  1. 【HTML】
  2. <button class="layui-btn test" lay-data="{url: '/a/'}">上传图片</button>
  3. <button class="layui-btn test" lay-data="{url: '/b/', accept: 'file'}">上传文件</button>
  4. 【JS】
  5. upload.render({
  6. elem: '.test'
  7. ,done: function(res, index, upload){
  8. //获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
  9. var item = this.item;
  10. }
  11. })

更多支持的参数详见下表,合理的配置它们,应对各式各样的业务需求。

参数选项 说明 类型 默认值
elem 指向容器选择器,如:elem: '#id'。也可以是DOM对象 string/object -
url 服务端上传接口,返回的数据规范请详见下文 string -
data 请求上传接口的额外参数。如:data: {id: 'xxx'}
从 layui 2.2.6 开始,支持动态值,如:

</>code

  1. data: {
  2. id: function(){
  3. return $('#id').val();
  4. }
  5. }
object -
headers 接口的请求头。如:headers: {token: 'sasasas'}。注:该参数为 layui 2.2.6 开始新增
accept 指定允许上传时校验的文件类型,可选值有:images(图片)、file(所有文件)、video(视频)、audio(音频) string images
acceptMime 规定打开文件选择框时,筛选出的文件类型,值为用逗号隔开的 MIME 类型列表。如:
acceptMime: 'image/*'(只显示图片文件)
acceptMime: 'image/jpg, image/png'(只显示 jpg 和 png 文件)
注:该参数为 layui 2.2.6 开始新增
string images
exts 允许上传的文件后缀。一般结合 accept 参数类设定。假设 accept 为 file 类型时,那么你设置 exts: 'zip|rar|7z' 即代表只允许上传压缩格式的文件。如果 accept 未设定,那么限制的就是图片的文件格式 string jpg|png|gif|bmp|jpeg
auto 是否选完文件后自动上传。如果设定 false,那么需要设置 bindAction 参数来指向一个其它按钮提交上传 boolean true
bindAction 指向一个按钮触发上传,一般配合 auto: false 来使用。值为选择器或DOM对象,如:bindAction: '#btn' string/object -
field 设定文件域的字段名 string file
size 设置文件最大可允许上传的大小,单位 KB。不支持ie8/9 number 0(即不限制)
multiple 是否允许多文件上传。设置 true即可开启。不支持ie8/9 boolean false
number 设置同时可上传的文件数量,一般配合 multiple 参数出现。
注意:该参数为 layui 2.2.3 开始新增
number 0(即不限制)
drag 是否接受拖拽的文件上传,设置 false 可禁用。不支持ie8/9 boolean true
回调
choose 选择文件后的回调函数。返回一个object参数,详见下文 function -
before 文件提交上传前的回调。返回一个object参数(同上),详见下文 function -
done 执行上传请求后的回调。返回三个参数,分别为:res(服务端响应信息)、index(当前文件的索引)、upload(重新上传的方法,一般在文件上传失败后使用)。详见下文 function -
error 执行上传请求出现异常的回调(一般为网络异常、URL 404等)。返回两个参数,分别为:index(当前文件的索引)、upload(重新上传的方法)。详见下文 function -
上传接口

设定一个 URL 地址给 url 参数,用来告诉 upload 模块的服务端上传接口。像你平时使用Ajax一样。如:

</>code

  1. upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/' //必填项
  4. ,method: '' //可选项。HTTP类型,默认post
  5. ,data: {} //可选项。额外的参数,如:{id: 123, abc: 'xxx'}
  6. });

该接口返回的相应信息(response)必须是一个标准的 JSON 格式,如:

Responsecode

  1. {
  2. "code": 0
  3. ,"msg": ""
  4. ,"data": {
  5. "src": "http://cdn.layui.com/123.jpg"
  6. }
  7. }

注意1:你不一定非得按照上述格式返回,只要是合法的 JSON 字符即可。其响应信息会转化成JS对象传递给 done 回调。
注意2:如果上传后,出现文件下载框(一般为ie下),那么你需要在服务端对response的header设置 Content-Type: text/html

选择文件的回调

在文件被选择后触发,该回调会在 before 回调之前。一般用于非自动上传(即 auto: false )的场景,比如预览图片等。

</>code

  1. upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/'
  4. ,auto: false //选择文件后不自动上传
  5. ,bindAction: '#testListAction' //指向一个按钮触发上传
  6. ,choose: function(obj){
  7. //将每次选择的文件追加到文件队列
  8. var files = obj.pushFile();
  9. //预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
  10. obj.preview(function(index, file, result){
  11. console.log(index); //得到文件索引
  12. console.log(file); //得到文件对象
  13. console.log(result); //得到文件base64编码,比如图片
  14. //obj.resetFile(index, file, '123.jpg'); //重命名文件名,layui 2.3.0 开始新增
  15. //这里还可以做一些 append 文件列表 DOM 的操作
  16. //obj.upload(index, file); //对上传失败的单个文件重新上传,一般在某个事件中使用
  17. //delete files[index]; //删除列表中对应的文件,一般在某个事件中使用
  18. });
  19. }
  20. });

事实上这是一个非常实用的存在,可轻松应对复杂的列表文件上传管理。具体可移步到 示例 页面,里面有一个文件列表的小例子。

文件上传前的回调

choose 回调之后、done/error 回调之前触发。返回的参数完全类似 choose 回调。一般用于上传完毕前的loading、图片预览等。

</>code

  1. upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/'
  4. ,before: function(obj){ //obj参数包含的信息,跟 choose回调完全一致,可参见上文。
  5. layer.load(); //上传loading
  6. }
  7. ,done: function(res, index, upload){
  8. layer.closeAll('loading'); //关闭loading
  9. }
  10. ,error: function(index, upload){
  11. layer.closeAll('loading'); //关闭loading
  12. }
  13. });
上传接口请求成功的回调

在上传接口请求完毕后触发,但文件不一定是上传成功的,只是接口的响应状态正常(200)。回调返回三个参数,分别为:服务端响应信息当前文件的索引重新上传的方法

</>code

  1. upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/'
  4. ,done: function(res, index, upload){
  5. //假设code=0代表上传成功
  6. if(res.code == 0){
  7. //do something (比如将res返回的图片链接保存到表单的隐藏域)
  8. }
  9. //获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
  10. var item = this.item;
  11. //文件保存失败
  12. //do something
  13. }
  14. });
上传请求失败的回调

当请求上传时出现异常时触发(如网络异常、404/500等)。回调返回两个参数,分别为:当前文件的索引重新上传的方法

</>code

  1. upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/'
  4. ,error: function(index, upload){
  5. //当上传失败时,你可以生成一个“重新上传”的按钮,点击该按钮时,执行 upload() 方法即可实现重新上传
  6. }
  7. });
多文件上传完毕后的状态回调

只有当开启多文件时(即 multiple: true),该回调才会被触发。回调返回一个 object 类型的参数,包含一些状态数据:

</>code

  1. upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/'
  4. ,multiple: true
  5. ,allDone: function(obj){ //当文件全部被提交后,才触发
  6. console.log(obj.total); //得到总文件数
  7. console.log(obj.successful); //请求成功的文件数
  8. console.log(obj.aborted); //请求失败的文件数
  9. }
  10. ,done: function(res, index, upload){ //每个文件提交一次触发一次。详见“请求成功的回调”
  11. }
  12. });
文件上传进度的回调

在网速一般的情况下,大文件的上传通常需要一定时间的等待,而浏览器并不会醒目地告知你它正在努力地上传中,此时为了提升用户体验,我们可以通过该回调制作一个进度条。注:该回调为 layui 2.5.5 新增

</>code

  1. upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/'
  4. ,progress: function(n, elem, res, index){
  5. var percent = n + '%' //获取进度百分比
  6. element.progress('demo', percent); //可配合 layui 进度条元素使用
  7. console.log(elem); //得到当前触发的元素 DOM 对象。可通过该元素定义的属性值匹配到对应的进度条。
  8. console.log(res); //得到 progress 响应信息
  9. console.log(index); //得到当前上传文件的索引,多文件上传时的进度条控制,如:
  10. element.progress('demo-'+ index, n + '%'); //进度条
  11. }
  12. });
重载实例

有时你可能需要对 upload.render() 实例进行重载,通过改变一些参数(如将上传文件重置为只上传图片等场景)来重置功能。如:

</>code

  1. //创建一个实例
  2. var uploadInst = upload.render({
  3. elem: '#id'
  4. ,url: '/api/upload/'
  5. ,size: 1024*5 //限定大小
  6. });
  7. //重载该实例,支持重载全部基础参数
  8. uploadInst.reload({
  9. accept: 'images' //只允许上传图片
  10. ,acceptMime: 'image/*' //只筛选图片
  11. ,size: 1024*2 //限定大小
  12. });

注意:该方法为 layui 2.5.0 开始新增

重新上传

在执行 upload.render(options) 方法时,其实有返回一个实例对象,以便对完成重新上传等操作。注意:这是对当前上传队列的全局重新上传,而 choose 回调返回的 obj.upload(index, file) 方法则是对单个文件进行重新上传。如:

</>code

  1. var uploadInst = upload.render({
  2. elem: '#id'
  3. ,url: '/api/upload/'
  4. ,choose: function(obj){
  5. obj.preview(function(index, file, result){
  6. //对上传失败的单个文件重新上传,一般在某个事件中使用
  7. //obj.upload(index, file);
  8. });
  9. }
  10. });
  11. //重新上传的方法,一般在某个事件中使用
  12. //uploadInst.upload();
跨域上传

有些时候,可能会涉及到文件跨域操作,过去版本的 upload 模块最大的缺陷恰恰在于这里。而从 layui 2.0 的版本开始,我们已经对 跨域做了支持。但鉴于代码的冗余度等多方面考虑,在IE9以下版本环境中,仍然不支持跨域。其它所有版本的IE和Chrome/FireFox等高级浏览器均支持。

那么,需要你怎么做?通常来说,是借助 CORS(跨资源共享) 方案,即对接口所在的服务器设置:Access-Control-Allow-Origin 详见Google,配置起来还是挺简单的。而至于域名限制,一般是服务端程序中去做处理。这里不做过多赘述。