AjaxFileUpload需求

传统的form表单方式上传文件,  必然会刷新整个页面。 那么在不刷新界面的情况下实现文件的上传呢?

在 HTML4下, 聪明的程序员们发明了 ajax file upload 方式(form + hidden iframe方式), 为本文介绍的对象。

 在HTML5中XMLHttpRequest实现了异步上传文件(介绍见 http://wenzhixin.net.cn/2013/11/28/ajax_file_upload_html5)。

开源项目

官网为 https://github.com/davgothic/AjaxFileUpload

此插件支持, 选择文件后,  立刻上传文件, 整体页面不刷新,  并可以根据后台返回的json报给用户上传的状况。

使用说明

此插件是基于jquery库,  需要引用jquery库,

    <scripttype="text/javascript"src="jquery-1.6.1.min.js"></script><scripttype="text/javascript"src="../jquery.ajaxfileupload.js"></script>

文件控件(使用此插件 form都不用  写):

    <formmethod="post"action=""enctype="multipart/form-data"><label>File Input: <inputtype="file"name="file"id="demo1" /></label><divid="uploads"></div></form>

使用此插件初始化控件:

    <scripttype="text/javascript">$(document).ready(function() {$("#demo1").AjaxFileUpload({onComplete:function(filename, response) {$("#uploads").append($("<img />").attr("src", filename).attr("width",200));}});});</script>

后台实现PHP参考:

<?php/***This is just an example of how a file could be processed from the* upload script. It should be tailored to your own requirements.*/
// Only acceptfiles with these extensions$whitelist = array('jpg', 'jpeg', 'png', 'gif');$name      =null;$error     = 'No file uploaded.';if (isset($_FILES)) {if (isset($_FILES['file'])) {$tmp_name = $_FILES['file']['tmp_name'];$name     = basename($_FILES['file']['name']);$error    = $_FILES['file']['error'];if ($error ===UPLOAD_ERR_OK) {$extension = pathinfo($name,PATHINFO_EXTENSION);if (!in_array($extension, $whitelist)) {$error = 'Invalid file type uploaded.';}else{move_uploaded_file($tmp_name, $name);}}}
}
echo json_encode(array('name'  => $name,'error' => $error,));die();

定制接口

四个定制接口, 可以定制内容包括:

1 上传url (定制自定义的 action)

2  提交submit事件 (例如对文件后缀校验不成功, 不上传)

3  选中文件change事件 (定制选中文件后的 等待进度条等)

4 提交完成后的响应事件 complete (提交成功后, 将提交结果添加到列表中)

    <formmethod="post"action=""enctype="multipart/form-data"><label>File Input: <inputtype="file"name="file"id="demo1" /></label></form><scripttype="text/javascript"src="jquery-1.6.1.min.js"></script><scripttype="text/javascript"src="../jquery.ajaxfileupload.js"></script><scripttype="text/javascript">$(document).ready(function() {varinterval;functionapplyAjaxFileUpload(element) {$(element).AjaxFileUpload({action:"upload.php",onChange:function(filename) {//Create a span element to notify the user of an upload in progressvar$span=$("<span />").attr("class", $(this).attr("id")).text("Uploading").insertAfter($(this));$(this).remove();interval=window.setInterval(function() {vartext=$span.text();if(text.length< 13) {$span.text(text+ ".");}else{$span.text("Uploading");}},200);},onSubmit:function(filename) {//Return false here to cancel the upload/*var $fileInput = $("<input />").attr({type: "file",name: $(this).attr("name"),id: $(this).attr("id")});$("span." + $(this).attr("id")).replaceWith($fileInput);applyAjaxFileUpload($fileInput);return false;*///Return key-value pair to be sent along with the filereturn true;},onComplete:function(filename, response) {window.clearInterval(interval);var$span=$("span." +$(this).attr("id")).text(filename+ " "),$fileInput=$("<input />").attr({type:"file",name: $(this).attr("name"),id: $(this).attr("id")});if(typeof(response.error)=== "string") {$span.replaceWith($fileInput);applyAjaxFileUpload($fileInput);alert(response.error);return;}$("<a />").attr("href","#").text("x").bind("click",function(e) {$span.replaceWith($fileInput);applyAjaxFileUpload($fileInput);}).appendTo($span);}});}applyAjaxFileUpload("#demo1");});</script>

实现原理

参考下面文章的说明:

http://wenzhixin.net.cn/2013/11/27/ajax_file_upload_iframe

此处结合此开源项目的代码介绍下:

1、 应用 AjaxFileUpload 到 file控件后, 此file控件就绑定了 change事件, 事件函数为 onChange

return this.each(function() {var $this = $(this);if ($this.is("input") && $this.attr("type") === "file") {$this.bind("change", onChange);}});

2、 用户选择文件后, 触发 change事件, 调用 onChange 函数

此函数, 先克隆一个 file控件, 并将 此克隆控件,  也使用 AjaxFileUpload  初始化(即绑定了 onChange函数,地位与原始控件相同了),

     并将此控件 插入到 原始控件前。

                $clone   = $element.removeAttr('id').clone().attr('id', id).AjaxFileUpload(options),。。。。。            // We append a clone since the original input will be destroyed            $clone.insertBefore($element);

后创建  隐藏的 iframe, 并初始化 iframe的 load事件(form提交后响应的框架), 事件函数即为 响应处理函数:

iframe   = createIframe(),
。。。。iframe.bind("load", {element: $clone, form: form, filename: filename}, onComplete);

后创建提交的form, 将form的提交事件绑定为onSubmit, 并做提交动作:

form     = createForm(iframe);
。。。。。form.append($element).bind("submit", {element: $clone, iframe: iframe, filename: filename}, onSubmit).submit();

3、 2步骤中form提交后, 文件上传成功, 在iframe的load事件被触发, 执行onComplete函数, 将执行结果进行处理, 处理完毕后将 onChange中创建的 form 和 iframe删除:

function onComplete (e) {var $iframe  = $(e.target),doc      = ($iframe[0].contentWindow || $iframe[0].contentDocument).document,response = doc.body.innerHTML;if (response) {response = $.parseJSON(response);} else {response = {};}// 自定义的处理逻辑settings.onComplete.call(e.data.element, e.data.filename, response);// Remove the temporary form and iframe
e.data.form.remove();$iframe.remove();}

change事件只生效一次说明

如果对 file 控件应用 ajaxfileupload 控件初始化后, 接着设置 一个附加的 change 事件, 在第一用户选择文件上传后, 会丢失, 是因为 文件控件被替换为clone体, 但是clone体没带有old event, 生效代码为 clone参数为空, 意味着浅拷贝:

function onChange(e) {var $element = $(e.target),id       = $element.attr('id'),$clone   = $element.removeAttr('id').clone().attr('id', id).AjaxFileUpload(options),filename = $element.val().replace(/.*(\/|\\)/, ""),iframe   = createIframe(),form     = createForm(iframe);// We append a clone since the original input will be destroyed$clone.insertBefore($element);

解决方法,使用代理:

$(document).on('change', '#upload', function() {});

参考:

http://wenzhixin.net.cn/2013/11/26/jquery_file_upload_change_once

AjaxFileUpload 方法与原理分析相关推荐

  1. 【JVM系列3】方法重载和方法重写原理分析,看完这篇终于彻底搞懂了

    深入分析Java虚拟机中方法执行流程及方法重载和方法重写原理 前言 思考 栈帧 局部变量表(Local Variables) 操作数栈(Operand Stacks) 动态连接(Dynamic Lin ...

  2. hashmap冲突的解决方法以及原理分析

    HashMap冲突问题看这个就行了 在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样.当程序试图将多个 k ...

  3. MessageQueue.IdleHandler接口使用方法以及原理分析

    https://bbs.51cto.com/thread-1094228-1.html MessageQueue.IdleHandler可以用来在线程空闲的时候,指定一个操作:有点类似Handler. ...

  4. HashMap 中 hash 冲突的解决方法及原理分析

    我们最先衰老的不是容貌,而是不顾一切的闯劲.有时候,要敢于背上超出自己预料的包袱,真的努力后,你会发现自己要比想象的优秀很多. HashMap冲突的解决方法比较考验一个开发者解决问题的能力. 在Jav ...

  5. (5.2)【苹果系统中数据隐藏】Stego Sec使用方法、原理分析

    目录 一.简介: 二.使用方法: 第一步:选择图像 第二步:输入隐藏信息 第三步:处理图像 三.数据隐藏方法分析 隐藏信息的内容: 分析: 推测: 总结: 一.简介: 可以在照片(直接拍摄.存储在 i ...

  6. mysqldump备份数据不锁表的加参数方法及原理分析

    mysqldump命令的备份用法分析-锁表不锁表 mysqldump默认的字符集是utf8 /etc/my.cnf添加如下两行文件,重启mysql服务,以输出日志方便分析general_log=on ...

  7. jQuery的ready方法实现原理分析

    jQuery中的ready方法实现了当页面加载完成后才执行的效果,但他并不是window.onload或者doucment.onload的封装,而是使用 标准W3C浏览器DOM隐藏api和IE浏览器缺 ...

  8. 高通手机900E变砖救活方法及原理分析

    救活神器--刷机工程线 使用普通数据线简单改造即可: 1. 将数据线外皮剥开 2. 将绿线(D+)和黑线(地线)的外皮剥开 3. 将剥开的绿线和地线短接即可. 用改造好的工程线连接手机和电脑, 然后长 ...

  9. 【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行原理分析

    文章目录 一.查看使用 AspectJ 后生成的 Class 字节码类 二.AspectJ 的本质 一.查看使用 AspectJ 后生成的 Class 字节码类 在 Android Studio 中查 ...

最新文章

  1. html怎么让导航栏平均分布,CSS 怎么让按钮平均分布
  2. ms sql 索引(一)
  3. webstorm前端调用后端接口_一篇前端同学对后端接口的吐槽
  4. ReactJS入门之生命周期
  5. 枚举算法:试统计正整数n的阶层n!=1*2*...*n尾部连续零的个数。
  6. 共享文件夹只能连接20人_英语正能量 | 快乐可以与人共享,苦难却只能自己坚强...
  7. 解决办法:error: ‘unordered_map’ in namespace ‘std’ does not name a template type
  8. Extjs的文件上传问题
  9. 面试题之wait()和sleep()方法区别
  10. matlab语法归纳
  11. Word中插入目录时未找到目录项
  12. 在质疑声中,81岁的丁肇中或将证实“反物质世界”的存在
  13. Bean with name ‘XX‘ has been injected into other beans [XX,XX] in its raw version.......... 错误分析及解决
  14. 信息安全-网络物理隔离技术原理与应用
  15. 最新出炉--IOS自动化测试环境搭建(Python Java)
  16. AutodeskCAD卸载后无法再次安装?完美解决!
  17. MATLAB-中文乱码问题解决
  18. 杭电 1248 寒冰王座
  19. 手机制作html蓝底白字,怎么制作html5手机页面?
  20. 简单好用的 SemVer: 如何命名你的应用版本

热门文章

  1. python的none是什么-python 中None,is和==的深入探讨
  2. 使用python hashlib模块给明文字符串加密,以及如何撞库破解密码
  3. Linux中的chmod权限问题
  4. oa php mysql_PHP+MYSQL的OA为何没有Java的值钱?
  5. LA3942 Remember the Word(Trie+DP)
  6. shell脚本中的输入输出
  7. 网络编程学习笔记(getservbyname和getservbyport函数)
  8. js经典校验之注册与登录校验
  9. ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry ’1′ for key
  10. MySQL 第七天(核心优化一)