本文为转载内容,但所讲内容亲身试验证明可用,转载过来希望能帮助到有需要的人。

转载地址:http://blog.csdn.net/kongjiea/article/details/24290373#comments

Ajax解决了不刷新页面提交表单,但是却没有解决文件上传不刷新页面,当然也有其它技术让不刷新页面而提交文件,该技术主要是利用隐藏的iFrame, 较Ajax要麻烦许多,而且其提交方式依然在底层是使用的表单file,这里我们不详谈。而且如果是提交较小的文件,我们能接受,如果提交的文件较大,我 们便要忍受很长的等待时间,而浏览器却没有任何提示,我们也没有办法知道文件上传的进度…

但是现在,网上出现了一个名为SWFUpload的上传组件,该组件利用Flash自身的文件提交技术而无需刷新页面,而且能够获取文件上传进度,可以提交多个文件,而且还能控制上传文件的大小,类型等信息。这么一个强大而易用的东西,你还在寻找么?

下面就是是SWFUupload的简易教程,服务端大同小异,我这里以php为例。(该教程基于SWFUpload2.2.0.1,虽然 SWFUpload v2.5.0 Beta 3已经放出,但是考虑到是测试版,肯定用不稳定的因素,我决定将稳定的2.2.0.1作为本次学习的版本)。

下载SWFUpload

下载地址:swfupload.googlecode 下载完后解压到某个目录,我这里放在labs.goodje 自需要保留目录下的swfupload.js,Flash/swfupload.swf两个文件和plugins目录,其它的都可以删掉。

  • swfupload.js: swfupload的js脚本,封装swfupload.swf的各种接口供js调用,简化操作。
  • swfupload.swf: swfupload的核心所在,上传多个文件,提供上传进度,限制文件容量尺寸等提优于于上传表单功能的工具,实质是一个flash。

快速入门

新增一个上传页面,我们放在swfu下,但不一定非要放在swfu下,命名为tutor-1.html。

head中插入用于引入swfupload.js的代码

<script src="swfupload.js"></script>

然我我们还需要一个swfupload占位符和一个上传按钮。占位符用于当swfupload载入并初始化后被swfupload按钮替换的一个dom元素。

<div id="swfu-placeholder"><!–swfupload文件选择按钮占位符,执行下面的js后,这里将被替换成swfupload上传按钮–></div>

  • <div><input type="button" onclick="swfu.startUpload();" value="上传" /></div>

接着,载入并初始化swfupload.swf。

var swfuOption = {//swfupload选项

  • upload_url : "http://labs.goodje", //接收上传的服务端url
  • flash_url : "http://labs.goodje",//swfupload压缩包解压后swfupload.swf的url
  • button_placeholder_id : "swfu-placeholder",//上传按钮占位符的id
  • file_size_limit : "20480",//用户可以选择的文件大小,有效的单位有B、KB、MB、GB,若无单位默认为KB
  • button_width: 200, //按钮宽度
  • button_height: 20, //按钮高度
  • button_text: ‘点我选择文件‘//按钮文字
  • }
  • var swfu = new SWFUpload(swfuOption);//初始化并将swfupload按钮替换swfupload占位符

这样,我们点击“点我选择文件”便可以上传文件了,是不是so easy。[查看demo]

另外我们非常建议在开发的过程中启用debug模式,这个东西非常管用,在swfuOption中添加一个debug:true就可以了。

还有一点要特别注意:如果你的swfupload.swf域名和upload_url目录不在同一个域名下,请在upload_url域名下的根目录下创建一个crossdomain.xml文件,该文件主要是出于安全考虑的设计,目的是防止跨域的请求。该文件内容请参考:Flex中实现跨域web service调用时crossdomain.xml的issue(中文),以及官方资料Adobe Cross Domain Policy FileSpecification(英文)

美化按钮

现在swfupload按钮是不是太丑了,用户肯定不会喜欢的,就连能不能点我觉得用户都会这么想。好吧,那现在我们来美化它把。

一. 加上背景图片。

按钮分别有四种状态:1. 正常情况 2. 鼠标经过 3. 鼠标按下 4. 按钮被禁用。

知道了这四种状态我们就可以开始制作图片了,图片宽度为按钮的宽度,高度为按钮高度的四倍,四种状态的背景图片分别从上至下排列,中间没有缝隙,最终效果可以是这个样子。

var swfuOption = {//swfupload选项

  • upload_url : "http://labs.goodje", //接收上传的服务端url
  • flash_url : "http://labs.goodje",//swfupload压缩包解压后swfupload.swf的url
  • button_placeholder_id : "swfu-placeholder",//上传按钮占位符的id
  • file_size_limit : "20480",//用户可以选择的文件大小,有效的单位有B、KB、MB、GB,若无单位默认为KB
  • button_width: 215, //按钮宽度
  • button_height: 45, //按钮高度
  • button_text: ‘点我选择文件‘,//按钮文字
  • button_image_url: "http://labs.goodje",//按钮背景图片路径
  • debug:true
  • }
  • var swfu = new SWFUpload(swfuOption);

这里修改了button_width,button_height并且新增了button_image_url参数。

二. 优化按钮文字

swfupload有个好处就是可以将背景图片和文字分离,这个做的比较好,要是换文字不要找设计来弄,直接改代码就行了,另外,文字支持html标 签,css控制样式,可以用来修改文字的字体颜色和大小,但是很坑爹的一点就是支持的html和css都不全,无法将文字剧中显示,这个太tm坑爹了。不 过好在swf选项提供了button_text_top_padding和button_text_left_padding选项,可以用来控制文字离按钮顶部和左边的距离,灰常蛋疼,因为就算你这次调好了,下次增加或删除了文字、修改了文字大小后都需要再调,调好后效果如下。

再附上代码:

var swfuOption = {//swfupload选项

  • upload_url : "http://labs.goodje", //接收上传的服务端url
  • flash_url : "http://labs.goodje",//swfupload压缩包解压后swfupload.swf的url
  • button_placeholder_id : "swfu-placeholder",//上传按钮占位符的id
  • file_size_limit : "20480",//用户可以选择的文件大小,有效的单位有B、KB、MB、GB,若无单位默认为KB
  • button_width: 215, //按钮宽度
  • button_height: 45, //按钮高度
  • button_text: ‘<span class="btn-txt">选择文件</span>‘,//按钮文字
  • button_text_style: ‘.btn-txt{color: #666666;font-size:20px;font-family:"微软雅黑"}‘,
  • button_text_top_padding: 6,
  • button_text_left_padding: 65,
  • button_image_url: "http://labs.goodje",//按钮背景图片路径
  • debug:true
  • }
  • var swfu = new SWFUpload(swfuOption);

这里分别修改了button_text,新增了button_text_style,button_text_top_padding以及button_text_left_padding。

高级应用

一. 事件

这里,所谓的事件就是因用户或计算机自动操作过程中产生的一些结果。

swfupload中包含很多事件,如用户点击“选择文件”按钮,文件选择框弹出前会触发fileDialogStart事件;用户点击上传按钮,swfupload响应并在上传前会触发uploadStart事件;文件上传过程中会不停的触发uploadProgress事件等等。

官方的解释:

SWFUpload在操作过程中会触发一系列事件,开发者可以利用这些回调的处理事件来控制UI,控制操作或者报告错误。

所有的事件都是在SWFUpload实例的上下文中调用的,因此在这些回调的事件中使用this能够直接访问到该触发该事件的实例对象。

所有事件应该在实例初始化时setting参数中预设完成。[详细事件列表]

二. 侦听事件

在swfupload初始化时,我们就必须侦听我们想侦听的事件,当然如果不侦听也不会出错,swfupload不做任何操作。

比如我们我们有这样的需求

  • 用户选择文件后自动上传,打开文件选择窗口后若未选择文件则不操作
  • 动态显示上传进度
  • 上传完成后提示文件上传是否成功
  • 增加“停止上传”按钮,用于在上传过程中停止上传,并将上传的文件回归到上传队列中
  • 文件上传过程中禁用“选择文件”按钮,文件上传完成或者中途取消上传恢复“选择文件”按钮

用户选择文件后自动上传需要侦听fileDialogComplete事件。我们要先定义一个函数:

function fileDialogComplete(selectedNum, queuedNum) {

  • if (queuedNum &gt; 0) {//选择并添加到上传队列的文件数大于0
  • this.startUpload();//开始上传
  • this.setButtonDisabled(true);//禁用上传按钮
  • }
  • }
  • //并在选项参数中加上该参数
  • file_dialog_complete_handler: fileDialogComplete

该函数用于侦听文件选择对话框关闭的事件,如果用户选择并且成功加入上传队列的文件数大于0即立即开始上传,另外禁用上传按钮,以防出错。

动态显示上传进度需要侦听uploadProgress事件,另外我们还要在html中插入一个div用于显示上传进度。

var statusE = document.getElementById(‘swfu-upload-status‘);//文件上传进度节点

  • function uploadProgress(file, curBytes, totalBytes) {
  • statusE.innerHTML = ['文件名:', file.name, '
  • 总尺寸:', totalBytes, 'B
  • 已上传:', curBytes, 'B
  • 进度:', parseInt((curBytes/totalBytes)*100), '%'].join(”);
  • }
  • //并且在选项参数中加上该参数
  • upload_progress_handler: uploadProgress

uploadProgress事件被触发后执行uploadProgress函数,并且给该函数传递三个参数,分别是当前上传的文件对象,当前以上传大小(单位:字节),当前上传的文件总大小(单位:字节)。

上传完成后提示文件上传是否成功需要至少侦听两个事件uploadError上传出错以及uploadSuccess上传成功,并建议侦听额外的一个uploadComplete事件,无论上传成功或者失败都会被触发。代码如下:

//上传过程中出错

  • function uploadError(file, errCode, msg) {
  • statusE.innerHTML += ['
  • 文件[', file.name, ']上传出错,出错代码:[', errCode, '],出错原因:‘, msg].join(”);
  • }
  • //上传成功
  • function uploadSuccess(file, data) {
  • statusE.innerHTML += ['
  • 文件[', file.name, ']上传成功,服务器返回信息:‘, data].join(”);
  • }
  • //上传完成,无论上传过程中出错还是上传成功,都会触发该事件,并且在那两个事件后被触发
  • function uploadComplete(file) {
  • statusE.innerHTML += ['
  • 文件[', file.name, ']结束上传‘].join(”);
  • this.setButtonDisabled(false);//恢复上传按钮
  • }
  • //并且在选项参数中加上该参数
  • upload_error_handler: uploadError,//文件上传出错
  • upload_success_handler: uploadSuccess,//文件上传成功
  • upload_complete_handler: uploadComplete//文件上传完成,在upload_error_handler或者upload_success_handler之后触发

uploadError函数的三个参数分别为:文件对象,出错代码以及出错明文信息。

uploadSuccess函数的两个参数分别为文件对象,服务器返回的信息。服务器返回的信息,实在是太大了,比如上传一张图片,经过服务器处理后需要返回在服务器上存储的url,然后供显示显示,等等。

uploadComplete函数只有一个参数,即文件对象。

但是,这里在windows上有一个bug,官方如此解释:

在window平台下,那么服务端的处理程序在处理完文件存储以后,必须返回一个非空值,否则uploadError/uploadSuccess事件都不会被触发,随后的uploadComplete事件也无法触发。

另外文件上传过程中禁用“选择文件”按钮,文件上传完成或者中途取消上传恢复“选择文件”按钮这个需求,其实已经完成了,分别在fileDialogComplete事件中开始上传之前禁用按钮,以及uploadComplete事件中恢复按钮。

细心的同学,可能已经发现了,我们这里只是讲解了单个文件的上传,并没有利用到swfupload利器的一大王牌功能——多文件上传,这个会在下一节更多参数中提到。

另外几个没有提到的几个事件也大同小异,这里我建议大件看文档(中文),师傅带进门,修行靠个人嘛,况且swfupload也不是个很复杂的东东。

更多参数

这里只提几个额外经常会用到的,一些边边角角的大家可以选择去看汉化官方文档。

Filedata,类似于表单上传控件的name属性,默认值为Filedata。这里不建议修改,因为在linux下的flash,无论怎么修改这个值,都没有效果。

post_params, post值。连同上传的文件一起提交到服务器上,这个东东也是比较有用的,比如可以验证用户是否允许上传文件等,另外可以用swfupload的 addPostParam/setPostParams/removePostParam/addFileParam/removeFileParam方 法修改该值,通常在上传文件额外还需要提交表单信息的时候会特别管用。

requeue_on_error, 是否将上传失败的的文件重新添加到上传队列的顶端,默认值为true。当文件上传失败或者停止上传触发uploadError事件,是否将上传失败的的文 件重新添加到上传队列的顶端,当然调用cancelUpload方法触发uploadError事件,不会将文件重新添加到上传队列中,而是会丢弃。

file_types,限制上传的文件类型,这个是非常有用且重要的,默 认值为*.*。另外当用户指向上传图片时可以设置为”*.jpg;*.jpeg;*.gif;*.png;*.bmp;”。另外有一点非常重要的就是,这 里只是浏览器端限制了上传的文件类型,服务端依然要验证上传的文件类型,否则可能是很危险的。

file_upload_limit,允许同时上传文件的数量,默认值为0,即不限制。当文件队列中的文件数,正在上传的文件以及已经上传成功的文件数只和超过了该值后,便不在允许添加文件。

file_queue_limit,允许队列存在的文件数量,默认值为0,即不限制。当文件队列中的文件数超过该值便不再允许添加文件。

button_action,点击swfupload按钮执行的动作,默认值为SWFUpload.BUTTON_ACTION.SELECT_FILES(多文件上传)。

官方如是说:
button_action (v2.2.0新增) 设置Flash
Button点击以后的动作。默认为SWFUpload.BUTTON_ACTION.SELECT_FILES,点击按钮将会打开多文件上传的对话框。
如果设置为SWFUpload.BUTTON_ACTION.SELECT_FILE,则为单文件上传。如果设置为
SWFUpload.BUTTON_ACTION.START_UPLOAD,则启动文件上传。

button_disabled,按钮是否禁用,默认值为false。

button_cursor,鼠标经过时的鼠标形状,默认值为SWFUpload.CURSOR.ARROW(箭头光标)。另外还有SWFUpload.CURSOR.HAND(手型),这里我非常建议设置为体验更好的SWFUpload.CURSOR.HAND,因为我觉得尽头光标很硬,不和善。

custom_settings,一些自定义的信息,默认值为一个空对象{}。这个没什么好说的,主要作用为存储一些和swfupload有关的信息,而且防止与其它变量或者函数重名。

custom_settings: {‘name‘:‘zhangshan‘,‘age‘:15}

  • alert(swfu.customSettings['name']);
  • alert(swfu.customSettings.age);

插件

插件不想多说,以Cookies插件为例讲一个。

这个插件主要目的为解决IE下的一个bug,flash不能将浏览器的cookie提交到服务器。

以至于服务端不能验证用户的登陆态,而在以插件形式允许的flash在FF或者chrome下就没有该问题。该插件的原理为使用js获取浏览器
cookie,存放到请求的post数据中一起提交给服务器。这里需要注意的一点是,用户提交的post数据如果和cookie中某个数据重名会将覆盖掉
cookie的值。

用法:

在head中载入插件的js,就可以了

<script src="plugins/swfupload.cookies.js"></script>

我们可以通过debug框看到cookie数据已经存入到post_params中了。

是不是soeasy吧,还是那句话,师傅带进门,修行靠个人,swfupload带给我们体验和可定制度都是非常高的,继续享受把。

官方网站:http://www.swfupload.org/(英文)

官方例子:http://demo.swfupload.org/(英文)

SWFUpload v2.2.0.1 手册: http://demo.swfupload.org/Documentation/(英文)

SWFUpload下载地址http://code.google本教程demo

SWFupload多图片上传入门教程的更多相关文章

  1. [上传下载] C# ImageUpload图片上传类教程与源码下载 (转载)

    点击下载 ImageUpload.zip 功能如下图片1.设置属性后上传图片,用法如下 /// <summary> /// 图片上传类 /// </summary> //--- ...

  2. Extjs swfUpload 多图片上传

    一.属性介绍   类型 默认值 描述 upload_url String   处理上传文件的服务器端页面的url地址,可以是绝对地址,也可以是相对地址,当为相对地址时相对的是当前代码所在的文档地址 p ...

  3. asp.net+swfupload 多图片批量上传(附源码下载)

    asp.net的文件上传都是单个文件上传方式,无法执行一次性多张图片批量上传操作,要实现多图片批量上传需要借助于flash,通过flash选取多个图片(文件),然后再通过后端服务进行上传操作. 本次教 ...

  4. php相册功能实现(包含php图片上传,后台管理,浏览和删除)教程例子

    相册功能实现(包含php图片上传,后台管理,浏览和删除)教程例子包括五个部分: 一.相册首页 <html> <head> <meta charset="utf- ...

  5. Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程

    Asp.Net Core Web Api图片上传及MongoDB存储实例教程(一) 图片或者文件上传相信大家在开发中应该都会用到吧,有的时候还要对图片生成缩略图.那么如何在Asp.Net Core W ...

  6. 【咸鱼教程】本地图片上传。动态GIF表情图生成

    本案例参考:http://emoji.decathlon.trustingme.cn/但是实现方式不一样. 教程目录一 head first二 打开本地图片功能三 拖拽和缩放手势,调整图片四 gifj ...

  7. 如何去除图片上的文字(PS使用教程)

    很多时候由于工作的需要,需要对我们的图片进行修改,修改的同时还想要保存我们的图片背景,所以很多人就不知道怎么弄了,小编跟大家分享一下使用PS如何简单的去掉图片上的文字,希望对大家有所帮助! 方法/步骤 ...

  8. 保姆级SpringBoot+Vue图片上传到阿里云OSS教程

    小二是新来的实习生,作为技术 leader,我给他安排了一个非常简单的练手任务,把前端 markdown 编辑器里上传的图片保存到服务器端,结果他真的就把图片直接保存到了服务器上,这下可把我气坏了,就 ...

  9. MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动

    MVC图片上传详解   MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...

随机推荐

  1. Oracle rownum影响运行计划

    今天调优一条SQL语句,因为SQL比較复杂,用autotrace非常难一眼看出哪里出了问题,直接上10046. SELECT AB.* FROM (SELECT A.*, rownum RN FROM ...

  2. linux搜索文件过程

    1.文件里的数据是放在磁盘的数据区中的,而一个文件名称则是通过相应的i节点与这些磁盘块联系起来.这些盘块的号码就存放在i节点的逻辑块数组i_zone[]中.在文件系统的一个文件夹中,当中全部文件名称信 ...

  3. Android中设置半个屏幕大小且居中的button布局 (layout_weight属性)

            先看例如以下布局 : 

  4. 2、Python列表和元组

    2.Python序列 序列是一种数据存储方式,类似于C语言的数组.简单的说序列是一块用来存储多个值的连续内存空间,同一个序列的元素通常是相关的. Python中常用的序列结构有列表.元组.字典.字符串 ...

  5. Django Admin site 显示问题

    Django Admin site 显示问题 今天配置了一下Django admin site,可是admin site的显示有一些问题,当我打开源码.訪问里面的admin 的css 文件时候,htt ...

  6. NOIP2017 小凯的疑惑 解题报告(赛瓦维斯特定理)

    题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的.现在小 凯想知道在无法准确支付的物品中,最贵的 ...

  7. POJ 3173 模拟

    按照题意模拟就好-- //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; in ...

  8. Ubuntu14.04下tensorflow安装

    自己电脑没装双系统,于是决定在虚拟机里装个tensorflow,以下是安装过程: 1.安装anaconda2 for Linux 官网下的话很慢,去清华的镜像网站下吧,我上一篇文章有网址 安装:bas ...

  9. Passpoint R1

    Passpoint R1 自从 Android 6.0 支持从网络下载包含配置文件和凭据信息的特殊文件来配置 Passpoint R1(第 1 版)凭据,Android 就一直支持 Passpoint ...

  10. 洛谷3833 [SHOI2012]魔法树

    SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点0是根节点 ...