XMLHttpRequest2-FormData上传文件方法封装及进度条的实现

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/article/details/51240496

FormData类型其实是在XMLHttpRequest 2级定义的,它是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)提供便利,使用FormData的最大优点就是我们可以异步上传一个二进制文件,兼容性需要IE10+。

构造函数

new FormData (form? : HTMLFormElement)

参数 form (可选) 一个HTML表单元素,可以包含任何形式的表单控件,包括文件输入框.

方法

  • append 给当前FormData对象添加一个键/值对.
void append(DOMString name, Blob value, optional DOMString filename);
void append(DOMString name, DOMString value);

如果指定的key不存在则会新增一条数据,如果key存在,则添加到数据的末尾

formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v1");

formData.get("k1"); // "v1"
formData.getAll("k1"); // ["v1","v2","v1"]
  • get
formData.get("name"); // 获取key为name的第一个值
formData.getAll("name"); // 返回一个数组,获取key为name的所有值

-set

我们可以通过set(key, value)来设置修改数据,如果指定的key不存在则会新增一条,如果存在,则会修改对应的value值。

formData.append("k1", "v1");
formData.set("k1", "1");
formData.getAll("k1"); // ["1"]
  • has
formData.append("k1", "v1");
formData.append("k2",null);

formData.has("k1"); // true
formData.has("k2"); // true
formData.has("k3"); // false
  • delete
formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v1");
formData.delete("k1");

formData.getAll("k1"); // []
  • entries 返回一个 iterator对象 ,此对象可以遍历访问FormData中的键值对。其中键值对的key是一个 USVString 对象;value是一个 USVString , 或者 Blob对象。

FormData上传文件方法的封装

;(function (window, document) {
    /**
     * @param selector : jquery selector
     * @param url : url of upload
     * @param file : object of file
     * @param beforeSend : function of validate
     * @param successF : function of success
     * @param errorF : function of error
     * @param uploadProgress : function of uploadProgress
     * @param otherRequestData : object of  otherRequestData
     * */
    var myUpload = function (option) {

        var file, formData, xhr, loadedevt, total, per, Url,  uploading;

        formData = new FormData();
        xhr = new XMLHttpRequest();
        url = option.url;
        file = option.file;

        //上传数据之前对数据的校验,常规包括不能null,文件类型,大小的限制
        if (option.beforeSend instanceof Function) {
            if (option.beforeSend(file) === false) { //校验在回调函数里实现,返回false校验不通过
                return false;
            }
        }

        //校验成功formData追加文件
        formData.append("files", file);

        //append 其他数据
        if(option.otherRequestData instanceof Object) {
            var _requestDate = option.otherRequestData;
            for(var key in _requestDate) {
                formData.append(key, _requestDate[key]);
            }
        }


        //事件回调
        // event callbacks
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if ((xhr.status >= 200 && xhr.status <= 300) || xhr.status === 304) {
                    option.successF instanceof Function && option.successF(xhr.responseText);
                }
                else {
                    option.errorF instanceof Function && option.errorF(xhr.responseText);
                }
            } else {
                option.errorF instanceof Function && option.errorF();
            }
        };

        //侦查当前附件上传情况
        /**
         * 附件的上传进度条方法在xhr.upload.onprogeress上,
         * 还有一个xhr.onprogress,是下载时候的进度条,***
         * */
        xhr.upload.onprogress = function (event) {
        // event.total是需要传输的总字节,event.loaded是已经传输的字节。如果event.lengthComputable不为真,则event.total等于0
         if (evt.lengthComputable) {
            loadedevt = event.loaded;
            total = event.total;
            per = Math.floor(100 * loadedevt / total);

        }
            //执行回调
            option.uploadProgress instanceof Function && option.uploadProgress(per);

        };

        xhr.open("post", url, true); //不能是GET, get请求数据发送只能拼接在URL后面
        xhr.setRequestHeader('Accept', 'application/json, text/javascript');

        xhr.send(formData);

    };

    window.myUpload = myUpload;
})(window, document);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏cloudskyme

OTL技术应用

什么是OTL:OTL 是 Oracle, Odbc and DB2-CLI TemplateLibrary 的缩写,是一个操控关系数据库的C++模板库,它目前几...

6026
来自专栏技术记录

前端插件——头像截图上传插件的使用(带后台)

效果图:实现上传头像,右边是预览,有三个大小,可以对头像进行裁剪 ? HTML: toParentData 和 img 返回的是图片裁剪后的base64编码。其...

1K5
来自专栏MasiMaro 的技术博文

windows 安全模型简介

操作系统中有些资源是不能由用户代码直接访问的,比如线程进程,文件等等,这些资源必须由系统级代码由RING3层进入到RING0层操作,并且返回一些标识供用户程序使...

2332
来自专栏coolblog.xyz技术专栏

Spring IOC 容器源码分析 - 余下的初始化工作

本篇文章是“Spring IOC 容器源码分析”系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的...

931
来自专栏Android开发与分享

【Android】Realm详解

64411
来自专栏deepcc

json学习笔记

2737
来自专栏潇涧技术专栏

Pury Project Analysis

Pury的源码:https://github.com/NikitaKozlov/Pury

892
来自专栏青青天空树

趣味题:恺撒Caesar密码(c++实现)

描述:Julius Caesar 生活在充满危险和阴谋的年代。为了生存,他首次发明了密码,用于军队的消息传递。假设你是Caesar 军团中的一名军官,需要把Ca...

742
来自专栏草根专栏

使用xUnit为.net core程序进行单元测试(下1)

第1部分: https://cloud.tencent.com/developer/article/1019835

3756
来自专栏草根专栏

使用xUnit为.net core程序进行单元测试(3)

请使用这个项目作为练习的开始: https://pan.baidu.com/s/1ggcGkGb 测试的分组 打开Game.Tests里面的BossEnemyS...

4345

扫码关注云+社区

领取腾讯云代金券