zoukankan      html  css  js  c++  java
  • 伪ajax上传文件

    伪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
  • 相关阅读:
    Python 处理时间的模块
    C# 委托在线程与UI界面之间的应用
    C# 自己动手实现Spy++(二)
    C# 自己动手实现Spy++(一)
    VS2008自定义快捷键设置
    C#深入解析委托——C#中为什么要引入委托
    C# 线程 在 sleep,suspend 之后 Abort 的方法
    C#多线程学习笔记之(abort与join配合使用)
    使用命名管道的OVERLAPPED方式实现非阻塞模式编程 .
    C++和C#进程之间通过命名管道通信(上)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3247111.html
Copyright © 2011-2022 走看看