如何通过AJAX和jQuery使用HTML5文件上传?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (108)

想要做的事情:

  • 上传整个形式的数据,其中一部分是单个文件
  • 使用Codeigniter的文件上传库

直到这里,一切都很好。数据在我需要的时候进入我的数据库。我也想通过AJAX帖子提交我的表单:

  • 使用本机HTML5文件API,而不是Flash或iframe解决方案
  • 最好与低级.ajax()jQuery方法交互

我想可以想象如何通过自动上传文件来实现这一点,当字段的值更改使用纯JavaScript时,我宁愿一举全部在jQuery中提交。我认为不可能通过查询字符串来完成,因为我需要传递整个文件对象。

提问于
用户回答回答于

有了jQuery(并且没有FormData API),可以使用这样的东西:

function readFile(file){
   var loader = new FileReader();
   var def = $.Deferred(), promise = def.promise();

   //--- provide classic deferred interface
   loader.onload = function (e) { def.resolve(e.target.result); };
   loader.onprogress = loader.onloadstart = function (e) { def.notify(e); };
   loader.onerror = loader.onabort = function (e) { def.reject(e); };
   promise.abort = function () { return loader.abort.apply(loader, arguments); };

   loader.readAsBinaryString(file);

   return promise;
}

function upload(url, data){
    var def = $.Deferred(), promise = def.promise();
    var mul = buildMultipart(data);
    var req = $.ajax({
        url: url,
        data: mul.data,
        processData: false,
        type: "post",
        async: true,
        contentType: "multipart/form-data; boundary="+mul.bound,
        xhr: function() {
            var xhr = jQuery.ajaxSettings.xhr();
            if (xhr.upload) {

                xhr.upload.addEventListener('progress', function(event) {
                    var percent = 0;
                    var position = event.loaded || event.position; /*event.position is deprecated*/
                    var total = event.total;
                    if (event.lengthComputable) {
                        percent = Math.ceil(position / total * 100);
                        def.notify(percent);
                    }                    
                }, false);
            }
            return xhr;
        }
    });
    req.done(function(){ def.resolve.apply(def, arguments); })
       .fail(function(){ def.reject.apply(def, arguments); });

    promise.abort = function(){ return req.abort.apply(req, arguments); }

    return promise;
}

var buildMultipart = function(data){
    var key, crunks = [], bound = false;
    while (!bound) {
        bound = $.md5 ? $.md5(new Date().valueOf()) : (new Date().valueOf());
        for (key in data) if (~data[key].indexOf(bound)) { bound = false; continue; }
    }

    for (var key = 0, l = data.length; key < l; key++){
        if (typeof(data[key].value) !== "string") {
            crunks.push("--"+bound+"\r\n"+
                "Content-Disposition: form-data; name=\""+data[key].name+"\"; filename=\""+data[key].value[1]+"\"\r\n"+
                "Content-Type: application/octet-stream\r\n"+
                "Content-Transfer-Encoding: binary\r\n\r\n"+
                data[key].value[0]);
        }else{
            crunks.push("--"+bound+"\r\n"+
                "Content-Disposition: form-data; name=\""+data[key].name+"\"\r\n\r\n"+
                data[key].value);
        }
    }

    return {
        bound: bound,
        data: crunks.join("\r\n")+"\r\n--"+bound+"--"
    };
};

//----------
//---------- On submit form:
var form = $("form");
var $file = form.find("#file");
readFile($file[0].files[0]).done(function(fileData){
   var formData = form.find(":input:not('#file')").serializeArray();
   formData.file = [fileData, $file[0].files[0].name];
   upload(form.attr("action"), formData).done(function(){ alert("successfully uploaded!"); });
});

使用FormData API,只需将表单的所有字段添加到FormData对象并通过$ .ajax({url:url,data:formData,processData:false,contentType:false,type:“POST”})发送它

热门问答

能提供腾讯区块链TBaas技术上链对接的流程图吗?

您好,非常感谢您的建议,我们目前确实没有整理完整的流程图,我们会尽快补齐并上线。 文字版的流程您可以先参考一下: 1,梳理业务场景和流程 2,规划区块链网络规模 3,购买区块链节点、组建区块链网络 4,根据业务场景编写智能合约 5,应用系统调用区块链的智能合约,与链交互 如果...... 展开详请

腾讯加固助手不能下载了吗?下载地址在哪里?MAC可以下载吗?我看只能在网页上加固,自己签名。?

腾讯云@移动安全

腾讯 · 移动开发工程师 (已认证)

腾讯云移动安全前端开发
推荐

乐固客户端已下线,可以使用移动应用在线加固https://console.cloud.tencent.com/ms/reinforce/list

可以自行签名打渠道包。

关于云直播的几个问题,望大佬解惑?

学生路人
推荐

1 海外单独计费

2 地址都是自己算的 可以变也可以不变

3 这个接口是拉流转推的 ,和播放不是一个东西哈 。

我用spark多个特征处理算子对原始数据进行处理,最后通过决策树训练分类,请问怎么导出最终模型?

腾讯智能钛AI开发者

腾讯云 · 智能钛产品团队 (已认证)

腾讯智能钛产品团队官方运营账号。分享产品最新动态,第一时间解答用户疑问。
推荐

您好,如果是使用组件自己编写的代码,可以使用 spark 中的 pipeline 功能,将多个功能串成一个流水线,再把流水线导出为 pmml 模型。详见 https://github.com/jpmml/jpmml-sparkml。

TencentOS例程,keil5编译报错no such file or directory?

Supowang

腾讯 · 高级工程师 (已认证)

腾讯物联网操作系统TencentOS tiny产品接口人---岁寒知松柏,做最好的自己!
推荐
您好!您的代码是早期的代码,请使用最新的github代码,代码下载地址:https://github.com/Tencent/TencentOS-tiny 或者腾讯工蜂 https://git.code.tencent.com/Tencent_Open_Source/Tence...... 展开详请

TBaaS 区块链,有哪些字段能展示在app界面上?公钥、数据证书、哈希值?

霜燃腾讯云区块链专家研发工程师
推荐
您好,回答您的问题: 问:公司有个项目要介入 TBaaS 区块链,有哪些字段能展示在app界面上的? 答:这里给出了几个查询链状态的接口(https://cloud.tencent.com/document/product/663/35190 ),接口中返回的字段,都可以作为字段...... 展开详请

扫码关注云+社区

领取腾讯云代金券