伪ajax上传文件

 

最近在折腾伪ajax异步上传文件。

网上搜索了一下,发现大部分方法的input file控件都局限于form中,如果是在form外的呢?

必须动态生成一个临时form和临时iframe,action指向上传文件URL,target指向临时iframe,同时在form中生成一个file控件;

但是出于安全的考虑,file控件都是只读的,不能动态设置其value值,所以在临时form中生成的file控件是永远无法绑定相应文件的,除非用户手动操作;

这时,我想到了jquery的clone方法,于是我便写了如下代码:

var $cloneFile = $file.clone(true);
$cloneFile.removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM"));

一测试,发现后台接收到的文件永远是空的,才知道jquery的clone方法对于file控件也是无能为力,想想也觉得有道理,还是基于安全的考虑。

经过一番思考,我想到了以下方法,还是基于jquery的clone,不过作了些调整:

//克隆file控件
var $cloneFile = $file.clone(true);
//将原来的file控件移动到临时form中
//以克隆的file控件代替原来的file控件
$file.hide().after($cloneFile).removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM"));

我将最原始的file控件移到了临时form中,而将克隆的代替了其原来位置。

测试,OK,搞定!以下是所有JS代码,基于sea.js的

/**
* @author weeksun23
* @date 2013-08-07 23:20
* @description 文件异步上传帮助类,它能帮助你将页面上任意一个file控件的文件异步上传到指定URL中
* @param $file file控件的jquery对象
* @param uploadUrl 上传URL
* @param type 上传文件的后缀限制 (jpg|gif|bmp|jpeg)
* @param callback 各种回调函数
* @dependency jquery
* @extra 占用了如下3个HTML ID:FILE_UPLOAD_TEMPDV FILE_UPLOAD_TEMPFORM FILE_UPLOAD_TEMPFRAME
*/
define(function(require, exports, module) {
function FileUpload($file,uploadUrl,type,callback){
this.$file = $file;
this.uploadUrl = uploadUrl;
this.type = type || null;
this.callback = $.extend({
complete : function(response) {}, //上传文件后回调
beforeUpload : function(fileName) {}, //上传前回调,返回false可中止上传
afterUpload : function() {} //触发上传后回调
},callback);
}
FileUpload.prototype.upload = function(){
var $file = this.$file,
filePath = $file.val(),
type = this.type,
fileFullName = filePath.substring(filePath.lastIndexOf("\\") + 1);
if(!filePath) return false;
if(type !== null){
var ext = fileFullName.substring(fileFullName.lastIndexOf(".") + 1);
if(type.indexOf(ext) === -1) return false;
}
var callback = this.callback;
if(callback.beforeUpload.call(this,fileFullName) === false) return false;
$("body").append(["<div id='FILE_UPLOAD_TEMPDV' style='display:none;'>",
"<form id='FILE_UPLOAD_TEMPFORM' enctype='multipart/form-data' method='post' action='",
this.uploadUrl,"' target='FILE_UPLOAD_TEMPFRAME'>",
"</form>",
"<iframe id='FILE_UPLOAD_TEMPFRAME' name='FILE_UPLOAD_TEMPFRAME'></iframe>",
"</div>"].join(""));
$("#FILE_UPLOAD_TEMPFRAME").on("load",function(){
var response = this.contentWindow.document.body.innerHTML;
callback.complete(response);
$(this).off("load");
$("#FILE_UPLOAD_TEMPDV").remove();
});
//克隆file控件
var $cloneFile = $file.clone(true);
//将原来的file控件移动到临时form中
//以克隆的file控件代替原来的file控件
$file.hide().after($cloneFile).removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM"));
this.$file = $cloneFile;
$("#FILE_UPLOAD_TEMPFORM").submit();
callback.afterUpload.call(this);
//通过验证 开始上传
return true;
};
module.exports = FileUpload;
});
 
 
分类: javascript

伪ajax上传文件的更多相关文章

  1. django上课笔记7-jQuery Ajax 和 原生Ajax-伪造的Ajax-三种Ajax上传文件方法-JSONP和CORS跨域资源共享

    一.jQuery Ajax 和 原生Ajax from django.conf.urls import url from django.contrib import admin from app01 ...

  2. IE8/9 JQuery.Ajax 上传文件无效

    IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...

  3. springMVC+jsp+ajax上传文件

    工作中遇到的小问题,做个笔记 实现springMVC + jsp + ajax 上传文件 HTML <body> <form id="myform" method ...

  4. Ajax上传文件进度条显示

    要实现进度条的显示,就要知道两个参数,上传的大小和总文件的大小 html5提供了一个上传过程事件,在上传过程中不断触发,然后用已上传的大 小/总大小,计算上传的百分比,然后用这个百分比控制div框的显 ...

  5. flask jQuery ajax 上传文件

    1.html 代码 <div> <form id="uploadForm" enctype="multipart/form-data" > ...

  6. ajax上传文件显示进度

    下面要做一个ajax上传文件显示进度的操作,文末有演示地址 这里先上代码: 1.前端代码 upload.html <!DOCTYPE html> <html lang="e ...

  7. 闲话ajax,例ajax轮询,ajax上传文件[开发篇]

    引语:ajax这门技术早已见怪不怪了,我本人也只是就自己真实的经验去总结一些不足道的话.供不是特别了解的朋友参考参考! 本来早就想写一篇关于ajax的文章的,但是前段时间一直很忙,就搁置了,趁着元旦放 ...

  8. ajax上传文件及进度显示

    之前在博文:原生ajax写法就提及过ajax2.0与1.0的差别是多了FormData和利用FormData文件上传(当然还有跨域,但不是本文的重点). 那么具体怎么样实现ajax上传文件呢? 一般来 ...

  9. django 基于form表单上传文件和基于ajax上传文件

    一.基于form表单上传文件 1.html里是有一个input type="file" 和 ‘submit’的标签 2.vies.py def fileupload(request ...

随机推荐

  1. Redis源代码分析(二十七)--- rio制I/O包裹

    I/O每个操作系统,它的一个组成部分.和I/O业务质量,在一定程度上也影响了系统的效率. 今天,我在了解了Redis中间I/O的,相同的,Redis在他自己的系统中.也封装了一个I/O层.简称RIO. ...

  2. crm创建和编辑全局选项集

    一个选项集就是可包含在一个实体中的某种类型的字段.它定义一组选项.当一个选项集显示在窗口中时,将使用下拉列表控件.当在 Advanced Find 中显示时,则使用选择列表控件.有时,开发者将选项集称 ...

  3. 左右lcm,gcd一些性质

    两个整数a,b  他们的最大公约数为n  最小公倍数为m  则有 a,b都能分解为有限个素数的积               12 = 2^2 * 3^1 * 5^0 , 30 = 2^1 * 3^1 ...

  4. Spring之使用Annotation注解开发项目

    我们也可以使用Annotation来实现注入操作,提高我们写代码的灵活性和效率.spring中要使用annotation,需要在配置文件中增加: <beans xmlns="http: ...

  5. 注意,WebDeploy服务会占用80端口。(Windows关闭了IIS,80端口任然被占用)

    最近遇到一个很奇怪的事情,Windows上的 IIS 网站 全关掉了,80端口仍然被占用.然后我新装了一台服务器,一个一个组件地装,装一个测一次,最后发现,WebDeploy这个组件,会占用80端口. ...

  6. 快速构建Windows 8风格应用25-数据绑定

    原文:快速构建Windows 8风格应用25-数据绑定 本篇博文主要介绍如何将UI元素与数据进行绑定.数据绑定的方向.数据更改通知.数据转换.数据绑定支持的绑定方案. 数据绑定是一种简单方式来显示数据 ...

  7. 亮点面试题&amp;&amp;实现Singleton(辛格尔顿)模式-JAVA版本

    称号:设计一个类.我们只能产生这个类的一个实例.(来自<剑指Offer>) 解析:仅仅能生产一个实例的类是实现Singleton(单例)模式的类型.因为设计模式在面向对象程序设计中起着举足 ...

  8. Maven入门笔记

    首先安装Maven,Maven的安装很简单,这里就不在说了. 先要确定把工程放在哪个路径下,创建一个文件夹并且在该文件夹下打开shell命令.可以先运行下面的命令,创建一个工程: mvn archet ...

  9. Redis3

    Redis到底该如何利用 上两篇受益匪浅,秉着趁热打铁,不挖到最深不罢休的精神,我决定追加这篇.上一篇里最后我有提到实现分级缓存管理应该是个可行的方案,因此今天特别实践了一下.不过缓存分级之后也发现了 ...

  10. Java泛型和集合之泛型介绍

    在声明一个接口和类的时候可以使用尖括号带有一个或者多个参数但是当你在声明属于一个接口或者类的变量的时候或者你在创建一个类实例的时候需要提供他们的具体类型.我们来看下下面这个例子 List<Str ...