图片/文件上传 - layui.upload
一切从小试牛刀开始。通常情况下,layui上传文件是借助 type="file" 的 input 标签来完成的,但非常遗憾的是,它不能很好地与其它表单元素并存,所以layui常常要单独为它做一个业务层面的“异步上传”,即先让图片上传,再和其它表单一起提交保存。下面是一个小示例:
这原本只是一个普通的 button,正是 upload 模块赋予了它“文件选择”的特殊技能。当然,你还可以随意定制它的样式,而不是只局限于按钮。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>upload模块快速使用</title>
<link rel="stylesheet" href="/static/build/layui.css" media="all">
</head>
<body>
<button type="button" class="layui-btn" id="test1">
<i class="layui-icon"></i>上传图片
</button>
<script src="/static/build/layui.js"></script>
<script>
layui.use('upload', function(){
var upload = layui.upload;
//执行实例
var uploadInst = upload.render({
elem: '#test1' //绑定元素
,url: '/upload/' //上传接口
,done: function(res){
//上传完毕回调
}
,error: function(){
//请求异常回调
}
});
});
</script>
</body>
</html>
一切看起来是那样的简单,乃至于我不得不凑一段文字来填充这一行的版面。这样好像与下文衔接起来会比较谐调的样子(自我感觉)
使用 upload 模块必须与 upload.render(options) 方法打交道,其中的 options即为基础参数,它是一个对象。
var upload = layui.upload; //得到 upload 对象
//创建一个上传组件
upload.render({
elem: '#id'
,url: ''
,done: function(res, index, upload){ //上传后的回调
}
//,accept: 'file' //允许上传的文件类型
//,size: 50 //最大允许上传的文件大小
//,……
})
从 layui 2.1.0 开始,允许你直接在元素上设定基础参数,如:
【HTML】
<button class="layui-btn test" lay-data="{url: '/a/'}">上传图片</button>
<button class="layui-btn test" lay-data="{url: '/b/', accept: 'file'}">上传文件</button>
【JS】
upload.render({
elem: '.test'
,done: function(res, index, upload){
//获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
var item = this.item;
}
})
更多支持的参数详见下表,合理的配置它们,应对各式各样的业务需求。
参数选项 | 说明 | 类型 | 默认值 |
---|---|---|---|
elem | 指向容器选择器,如:elem: '#id'。也可以是DOM对象 | string/object | - |
url | 服务端上传接口,返回的数据规范请详见下文 | string | - |
method | 上传接口的 HTTP 类型 | string | post |
data | 请求上传接口的额外参数。如:data: {id: 'xxx'} 从 layui 2.2.6 开始,支持动态值,如: codelayui.code
|
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一样。如:
upload.render({
elem: '#id'
,url: '/api/upload/' //必填项
,method: '' //可选项。HTTP类型,默认post
,data: {} //可选项。额外的参数,如:{id: 123, abc: 'xxx'}
});
该接口返回的相应信息(response)必须是一个标准的 JSON 格式,如:
{
"code": 0
,"msg": ""
,"data": {
"src": "http://cdn.layui.com/123.jpg"
}
}
注意1:你不一定非得按照上述格式返回,只要是合法的 JSON 字符即可。其响应信息会转化成JS对象传递给 done 回调。
注意2:如果上传后,出现文件下载框(一般为ie下),那么你需要在服务端对response的header设置 Content-Type: text/html
在文件被选择后触发,该回调会在 before 回调之前。一般用于非自动上传(即 auto: false )的场景,比如预览图片等。
upload.render({
elem: '#id'
,url: '/api/upload/'
,auto: false //选择文件后不自动上传
,bindAction: '#testListAction' //指向一个按钮触发上传
,choose: function(obj){
//将每次选择的文件追加到文件队列
var files = obj.pushFile();
//预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
obj.preview(function(index, file, result){
console.log(index); //得到文件索引
console.log(file); //得到文件对象
console.log(result); //得到文件base64编码,比如图片
//这里还可以做一些 append 文件列表 DOM 的操作
//obj.upload(index, file); //对上传失败的单个文件重新上传,一般在某个事件中使用
//delete files[index]; //删除列表中对应的文件,一般在某个事件中使用
});
}
});
事实上这是一个非常实用的存在,可轻松应对复杂的列表文件上传管理。具体可移步到 示例 页面,里面有一个文件列表的小例子。
在 choose 回调之后、done/error 回调之前触发。返回的参数完全类似 choose 回调。一般用于上传完毕前的loading、图片预览等。
upload.render({
elem: '#id'
,url: '/api/upload/'
,before: function(obj){ //obj参数包含的信息,跟 choose回调完全一致,可参见上文。
layer.load(); //上传loading
}
,done: function(res, index, upload){
layer.closeAll('loading'); //关闭loading
}
,error: function(index, upload){
layer.closeAll('loading'); //关闭loading
}
});
在上传接口请求完毕后触发,但文件不一定是上传成功的,只是接口的响应状态正常(200)。回调返回三个参数,分别为:服务端响应信息、当前文件的索引、重新上传的方法
upload.render({
elem: '#id'
,url: '/api/upload/'
,done: function(res, index, upload){
//假设code=0代表上传成功
if(res.code == 0){
//do something (比如将res返回的图片链接保存到表单的隐藏域)
}
//获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
var item = this.item;
//文件保存失败
//do something
}
});
当请求上传时出现异常时触发(如网络异常、404/500等)。回调返回三个参数,分别为:当前文件的索引、重新上传的方法
upload.render({
elem: '#id'
,url: '/api/upload/'
,error: function(index, upload){
//当上传失败时,你可以生成一个“重新上传”的按钮,点击该按钮时,执行 upload() 方法即可实现重新上传
}
});
只有当开启多文件时(即 multiple: true),该回调才会被触发。回调返回一个 object 类型的参数,包含一些状态数据:
upload.render({
elem: '#id'
,url: '/api/upload/'
,multiple: true
,allDone: function(obj){ //当文件全部被提交后,才触发
console.log(obj.total); //得到总文件数
console.log(obj.successful); //请求成功的文件数
console.log(obj.aborted); //请求失败的文件数
}
,done: function(res, index, upload){ //每个文件提交一次触发一次。详见“请求成功的回调”
}
});
注意:该回调为 layui 2.1.7 开始新增
在执行 upload.render(options) 方法时,其实有返回一个实例对象,以便对完成重新上传等操作。注意:这是对当前上传队列的全局重新上传,而 choose 回调返回的 obj.upload(index, file) 方法则是对单个文件进行重新上传。如:
var uploadInst = upload.render({
elem: '#id'
,url: '/api/upload/'
,choose: function(obj){
obj.preview(function(index, file, result){
//对上传失败的单个文件重新上传,一般在某个事件中使用
//obj.upload(index, file);
});
}
});
//重新上传的方法,一般在某个事件中使用
//uploadInst.upload();
有些时候,可能会涉及到文件跨域操作,过去版本的 upload 模块最大的缺陷恰恰在于这里。而从 layui 2.0 的版本开始,layui已经对 跨域做了支持。但鉴于代码的冗余度等多方面考虑,在IE9以下版本环境中,仍然不支持跨域。其它所有版本的IE和Chrome/FireFox等高级浏览器均支持。
那么,需要你怎么做?通常来说,是借助 CORS(跨资源共享) 方案,即对接口所在的服务器设置:Access-Control-Allow-Origin 详见Google,配置起来还是挺简单的。而至于域名限制,一般是服务端程序中去做处理。这里不做过多赘述。
上一篇: el表达式
下一篇: EL表达式自定义方法