jQuery-file-upload使用方法详解(一)
前言
在我们日常开发中,经常会遇到上传文件的问题,不同于别的表单提交等信息传输那样简单,文件上传是一个很复杂的功能,需要考虑很多的问题,比如拖拽上传,上传预览,上传不同文件类型,限制上传大小,多文件上传,大文件上传,断点续传,还要考虑各种兼容性等等。因此,我们急需一个好用的上传插件,而jQuery-file-upload就是其中最好用评分最高的一款上传插件,在Github上的start数量超过了2万8千多。今天我们就一起来学习一下它的用法。
jQuery-file-upload简介
jQuery-file-upload是一个文件上传组件,具有多文件上传选择,拖拽支持,进度条,验证并预览图片,支持音视频的jQuery插件。它还支持跨域上传,分片上传,断点续传,图片缩放等功能。它可以和任意的后台相配合(PHP, Python, Ruby on Rails, Java, Node.js, Go 等等)。
它的具体特性有如下这些:
-
多文件上传
支持一次性选择多个文件并同时上传
-
拖拽上传
支持从桌面或者文件管理器中拖拽文件至浏览器中上传
-
上传进度条
可以为每个独立的文件和所有的上传显示上传进度条
-
随时取消上传
可以随时取消每个独立的上传文件
-
随时恢复上传
取消上传的文件可以随时恢复上传,如果浏览器支持Blob这个API的话。
-
分片上传
大文件可以被切分成小的块分片上传,如果浏览器支持Blob这个API的话。
-
图片缩放
图片可以自动进行缩放,如果浏览器支持一些必须的JS API的话。
-
图片,音频,视频预览
可以本地预览图片,音频,视频等,如果浏览器支持一些必须的JS API的话。
-
不需要Flash等浏览器插件:
JQuery-file-upload的实现是基于标准的HTML5,不需要额外的浏览器插件。
-
兼容旧浏览器
如果浏览器支持XMLHttpRequests
的话,则使用XMLHttpRequests
进行上传,否则使用iframes
作为回调对于旧的浏览器。
-
支持元素表单文件上传
通过使用标准的HTML表单作为组件元素支持渐进增强功能。
-
跨域文件上传
通过使用跨域的XMLHttpRequests
或者iframe
跳转来支持跨域文件上传。
-
多个插件实例
允许在同一个页面使用多个插件实例。
- 可自定义化可拓展化
提供了一个接口去设置独立的配置和定义回调函数对于多个上传事件。 -
支持Multipart格式和文件流格式上传
文件可以被使用标准的multipart/form-data
格式上传或者文件流的格式上传(HTTP PUT file upload).
-
兼容任意类型后台
可以很好的和任意类型语言平台进行合作(PHP, Python, Ruby on Rails, Java, Node.js, Go 等等)。
在线DEMO地址
这是官方的在线测试jQuery-file-upload
的地址:https://blueimp.github.io/jQuery-File-Upload/
安装
在自己服务器上安装插件
虽然官方的DEMO实现包含了一些远程的文件,但是在你自己主机上使用的时候推荐把它们都下载下来。这些除了托管在谷歌的内容分发网络上的脚本,比github的demo页面更加地可靠。
-
在PHP网站上使用插件
去存档页面下载https://github.com/blueimp/jQuery-File-Upload/releasesjQuery-file-upload插件,解压后,将server/php
里面的文件上传到你自己的服务器即可。
-
在谷歌应用引擎上安装插件
去存档页面下载https://github.com/blueimp/jQuery-File-Upload/releasesjQuery-file-upload插件,然后上传server/gae-python
或者server/gae-go
目录到你的应用引擎实例,编辑app.yaml
文件,将jquery-file-upload
修改为你的APP ID,然后将刚才解压的目录,除了server
以外的整个目录上传到任意的主机,将main.js
中的url
改为你的地址即可。
-
在Nodejs中使用插件
通过NPM进行安装:
npm install blueimp-file-upload-node
启动服务:
./node_modules/blueimp-file-upload-node/server.js
将main.js
中的url
改为你的服务器地址即可。
-
在自定义化服务器中使用
在这里有其他的一些具体的其他语言服务器的配置教程https://github.com/blueimp/jQuery-File-Upload/wiki,修改你的main.js
中的url
或者你可以去掉配置项中的url
配置,然后在index.html
中修改表单的action
的地址即可。服务端返回的JSON数据应该类似下面这样:
{"files": [
{
"name": "picture1.jpg",
"size": 902604,
"url": "http:\/\/example.org\/files\/picture1.jpg",
"thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture1.jpg",
"deleteUrl": "http:\/\/example.org\/files\/picture1.jpg",
"deleteType": "DELETE"
},
{
"name": "picture2.jpg",
"size": 841946,
"url": "http:\/\/example.org\/files\/picture2.jpg",
"thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture2.jpg",
"deleteUrl": "http:\/\/example.org\/files\/picture2.jpg",
"deleteType": "DELETE"
}
]}
如果是返回错误信息,应该类似下面这样:
{"files": [
{
"name": "picture1.jpg",
"size": 902604,
"error": "Filetype not allowed"
},
{
"name": "picture2.jpg",
"size": 841946,
"error": "Filetype not allowed"
}
]}
如果删除了文件的话,返回值应该类似这样:
{"files": [
{
"picture1.jpg": true
},
{
"picture2.jpg": true
}
]}
注意:即使只有一个文件也应该返回files
数组的形式。
Content-Type
商议
文件上传插件利用iframe传输模块,用于IE和Opera等尚未支持XMLHTTPRequest
文件上传的浏览器。
如果iframe响应设置为application/json
,则基于iframe的上传需要JSON响应的content-type
为text/plain
或text/html
- 它们将显示不希望的下载对话框。
您可以使用Accept标头为文件上传响应提供不同的内容类型。 以下是Accept content-type
变体的(PHP)示例代码片段:
<?php
header('Vary: Accept');
if (isset($_SERVER['HTTP_ACCEPT']) &&
(strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
header('Content-type: application/json');
} else {
header('Content-type: text/plain');
}
?>
下面是Ruby on Rails
的代码示例:
def update_attachment
name = params[:attachment_name]
style = params[:attachment_style]
image = params[:user][name]
raise "No attachment #{name} for User!" unless User.attachment_definitions[name.to_sym]
current_user.update("#{name}" => image)
render(json: current_user.to_fileupload(name, style), content_type: request.format)
end
最小化安装
下载的包的示例都是使用bootstrap
完整的用户界面,如果我们需要自定义前端界面,就需要最小化安装。
一个最小化的基本的html页面如下:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>jQuery File Upload Example</title>
</head>
<body>
<input id="fileupload" type="file" name="files[]" data-url="server/php/" multiple>
<script src="js/vendor/jquery.min.js"></script>
<script src="js/vendor/jquery.ui.widget.js"></script>
<script src="js/jquery.iframe-transport.js"></script>
<script src="js/jquery.fileupload.js"></script>
<script>
$(function () {
$('#fileupload').fileupload({
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
});
}
});
});
</script>
</body>
</html>
如果你想要展示进度条的话,可以在配置项中添加:
$('#fileupload').fileupload({
/* ... */
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css(
'width',
progress + '%'
);
}
});
然后在页面上加入进度条元素:
<div id="progress">
<div class="bar" style="width: 0%;"></div>
</div>
如果你想要在上传的周期时间内将一个文件绑定在一个元素节点上,你可以使用context
选项(实际上它是jqery.ajax的一个选项):
$(function () {
$('#fileupload').fileupload({
dataType: 'json',
add: function (e, data) {
data.context = $('<p/>').text('Uploading...').appendTo(document.body);
data.submit();
},
done: function (e, data) {
data.context.text('Upload finished.');
}
});
});
如果你想要点击一个按钮然后开始上传的话,也很容易:
$(function () {
$('#fileupload').fileupload({
dataType: 'json',
add: function (e, data) {
data.context = $('<button/>').text('Upload')
.appendTo(document.body)
.click(function () {
data.context = $('<p/>').text('Uploading...').replaceAll($(this));
data.submit();
});
},
done: function (e, data) {
data.context.text('Upload finished.');
}
});
});
启用本地图片缩放
首先需要添加下面的所有脚本文件:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<script src="js/vendor/jquery.ui.widget.js"></script>
<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
<!-- The Canvas to Blob plugin is included for image resizing functionality -->
<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
<script src="js/jquery.iframe-transport.js"></script>
<!-- The basic File Upload plugin -->
<script src="js/jquery.fileupload.js"></script>
<!-- The File Upload processing plugin -->
<script src="js/jquery.fileupload-process.js"></script>
<!-- The File Upload image preview & resize plugin -->
<script src="js/jquery.fileupload-image.js"></script>
然后设置选项disableImageResize
为false
,或者你也可以自定义:
$('#fileupload').fileupload({
url: '//jquery-file-upload.appspot.com/',
dataType: 'json',
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator && navigator.userAgent),
imageMaxWidth: 800,
imageMaxHeight: 800,
imageCrop: true // 裁切图片
})
依赖
-
强制性依赖
- jQueryv. 1.6+
- jQuery UI widget factoryv. 1.9+
- jQuery Iframe Transport plugin浏览器不支持XHR的时候需要
-
可选性依赖
- JavaScript Templates engine v. 2.5.4+ 被用来渲染选中上传文件的基本UI界面
- JavaScript Load Image library v. 1.13.0+: 预览缩放图片时候需要
- JavaScript Canvas to Blob polyfill v. 2.1.1+:预览缩放图片时候需要
- blueimp Gallery v. 2.15.1+: 当以Lightbox方式展现上传文件的时候需要
- Bootstrap v. 3.2.0+
- Glyphicons
-
跨域依赖
跨域文件上传使用了 Iframe Transport plugin,需要一个一个跳转去服务器去取回上传结果。我们的 例子使用了 result.html作为一个服务器的静态的跳转页面 。
JQuery-file-upload的官方仓库还包括了 jQuery XDomainRequest Transport plugin, 它可以限制跨域AJAX请求在IE8和IE9中。XDomainRequest
对象只允许GET
和POST
请求,不允许文件上传。在Demo中被使用来跨域删除文件服务。
浏览器支持
-
桌面浏览器
- Google Chrome
- Apple Safari 4.0+
- Mozilla Firefox 3.0+
- Opera 11.0+
- Microsoft Internet Explorer 6.0+
-
手机浏览器
- Apple Safari on iOS 6.0+
- Google Chrome on iOS 6.0+
- Google Chrome on Android 4.0+
- Default Browser on Android 2.3+
- Opera Mobile 12.0+
更多浏览器支持细节可以参考这个页面Extended browser support information
参考
更多精彩内容请看下一章:
jQuery-file-upload使用方法详解(二)