HTML5 Blob对象的具体使用


Posted in HTML / CSS onMay 22, 2020

写在前面

本篇主要总结Blob对象属性及作用,通过DEMO介绍Blob对象的应用场景。

Blob对象

一直以来,JS都没有比较好的可以直接处理二进制的方法。而Blob的存在,允许我们可以通过JS直接操作二进制数据。

一个Blob对象就是一个包含有只读原始数据的类文件对象。Blob对象中的数据并不一定得是JavaScript中的原生形式。File接口基于Blob,继承了Blob的功能,并且扩展支持了用户计算机上的本地文件。

Blob对象可以看做是存放二进制数据的容器,此外还可以通过Blob设置二进制数据的MIME类型。

创建Blob

通过构造函数

var blob = new Blob(dataArr:Array<any>, opt:{type:string});

dataArray:数组,包含了要添加到Blob对象中的数据,数据可以是任意多个ArrayBuffer,ArrayBufferView, Blob,或者 DOMString对象。

opt:对象,用于设置Blob对象的属性(如:MIME类型)

1、创建一个装填DOMString对象的Blob对象

HTML5 Blob对象的具体使用

2、创建一个装填ArrayBuffer对象的Blob对象

HTML5 Blob对象的具体使用

3、创建一个装填ArrayBufferView对象的Blob对象(ArrayBufferView可基于ArrayBuffer创建,返回值是一个类数组。如下:创建一个8字节的ArrayBuffer,在其上创建一个每个数组元素为2字节的“视图”)

HTML5 Blob对象的具体使用

通过Blob.slice()

此方法返回一个新的Blob对象,包含了原Blob对象中指定范围内的数据

Blob.slice(start:number, end:number, contentType:string)

start:开始索引,默认为0
end:截取结束索引(不包括end)
contentType:新Blob的MIME类型,默认为空字符串

HTML5 Blob对象的具体使用

var canvas = document.getElementById("canvas");
canvas.toBlob(function(blob){
    console.log(blob);
});

HTML5 Blob对象的具体使用

应用场景

前面提到,File接口基于Blob,继承了Blob的功能并进行了扩展,故我们可以像使用Blob一样使用File对象。

分片上传

通过Blob.slice方法,可以将大文件分片,轮循向后台提交各文件片段,即可实现文件的分片上传。
分片上传逻辑如下:

  • 获取要上传文件的File对象,根据chunk(每片大小)对文件进行分片
  • 通过post方法轮循上传每片文件,其中url中拼接querystring用于描述当前上传的文件信息;post body中存放本次要上传的二进制数据片段
  • 接口每次返回offset,用于执行下次上传

下面是分片上传的简单实现:

initUpload();

//初始化上传
function initUpload() {
    var chunk = 100 * 1024;   //每片大小
    var input = document.getElementById("file");    //input file
    input.onchange = function (e) {
        var file = this.files[0];
        var query = {};
        var chunks = [];
        if (!!file) {
            var start = 0;
            //文件分片
            for (var i = 0; i < Math.ceil(file.size / chunk); i++) {
                var end = start + chunk;
                chunks[i] = file.slice(start , end);
                start = end;
            }
            
            // 采用post方法上传文件
            // url query上拼接以下参数,用于记录上传偏移
            // post body中存放本次要上传的二进制数据
            query = {
                fileSize: file.size,
                dataSize: chunk,
                nextOffset: 0
            }

            upload(chunks, query, successPerUpload);
        }
    }
}

// 执行上传
function upload(chunks, query, cb) {
    var queryStr = Object.getOwnPropertyNames(query).map(key => {
        return key + "=" + query[key];
    }).join("&");
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://xxxx/opload?" + queryStr);
    xhr.overrideMimeType("application/octet-stream");
    
    //获取post body中二进制数据
    var index = Math.floor(query.nextOffset / query.dataSize);
    getFileBinary(chunks[index], function (binary) {
        if (xhr.sendAsBinary) {
            xhr.sendAsBinary(binary);
        } else {
            xhr.send(binary);
        }

    });

    xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                var resp = JSON.parse(xhr.responseText);
                // 接口返回nextoffset
                // resp = {
                //     isFinish:false,
                //     offset:100*1024
                // }
                if (typeof cb === "function") {
                    cb.call(this, resp, chunks, query)
                }
            }
        }
    }
}

// 每片上传成功后执行
function successPerUpload(resp, chunks, query) {
    if (resp.isFinish === true) {
        alert("上传成功");
    } else {
        //未上传完毕
        query.offset = resp.offset;
        upload(chunks, query, successPerUpload);
    }
}

// 获取文件二进制数据
function getFileBinary(file, cb) {
    var reader = new FileReader();
    reader.readAsArrayBuffer(file);
    reader.onload = function (e) {
        if (typeof cb === "function") {
            cb.call(this, this.result);
        }
    }
}

以上是文件分片上传前端的简单实现,当然,此功能还可以更加完善,如后台需要对合并后的文件大小进行校验;或者前端加密文件,全部上传完毕后后端解密校验等,此处不做赘述。

通过url下载文件

window.URL对象可以为Blob对象生成一个网络地址,结合a标签的download属性,可以实现点击url下载文件
实现如下:

createDownload("download.txt","download file");

function createDownload(fileName, content){
    var blob = new Blob([content]);
    var link = document.createElement("a");
    link.innerHTML = fileName;
    link.download = fileName;
    link.href = URL.createObjectURL(blob);
    document.getElementsByTagName("body")[0].appendChild(link);
}

执行后页面上会生成此Blob对象的地址,点击后可下载:

HTML5 Blob对象的具体使用

查看下载结果:

HTML5 Blob对象的具体使用

通过url显示图片

我们知道,img的src属性及background的url属性,都可以通过接收图片的网络地址或base64来显示图片,同样的,我们也可以把图片转化为Blob对象,生成URL(URL.createObjectURL(blob)),来显示图片。

HTML5 Blob对象的具体使用

小结

本文主要介绍了Blob对象的属性和使用场景,其实我们可以看到,Blob对象作为一个装填二进制数据的基本对象,其作用也仅仅是一个容器,而真正的业务功能则需要通过FileReader、URL、Canvas等对象实现,之后会继续对这些对象的功能和应用场景进行归纳。

参考资料

[1] MDN_Blob
[2] W3C Working Draft

到此这篇关于HTML5 Blob对象的具体使用的文章就介绍到这了,更多相关HTML5 Blob对象内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
CSS3教程(4):网页边框和网页文字阴影
Apr 02 HTML / CSS
10个很棒的 CSS3 开发工具 推荐
May 16 HTML / CSS
分享CSS3制作卡片式图片的方法
Jul 08 HTML / CSS
CSS3制作圆形滚动进度条动画的示例
Nov 05 HTML / CSS
CSS 说明横向进度条最后显示文字的实现代码
Nov 10 HTML / CSS
html5仿支付宝密码框的实现代码
Sep 06 HTML / CSS
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
Jun 03 HTML / CSS
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
Jan 09 HTML / CSS
将HTML5 Canvas的内容保存为图片借助toDataURL实现
May 20 HTML / CSS
为你的html5网页添加音效示例
Apr 03 HTML / CSS
HTML5 Canvas实现放大镜效果示例
Mar 25 HTML / CSS
html网页引入svg图片的4种方式
Aug 05 HTML / CSS
详解如何获取localStorage最大存储大小的方法
May 21 #HTML / CSS
html5用video标签流式加载的实现
May 20 #HTML / CSS
video.js支持m3u8格式直播的实现示例
May 20 #HTML / CSS
video实现有声音自动播放的实现方法
May 20 #HTML / CSS
基于html5 canvas做批改作业的小插件
May 20 #HTML / CSS
video下autoplay属性无效的解决方法(添加muted属性)
May 19 #HTML / CSS
html2canvas生成的图片偏移不完整的解决方法
May 19 #HTML / CSS
You might like
PHP产生随机字符串函数
2006/12/06 PHP
php 模拟GMAIL,HOTMAIL(MSN),YAHOO,163,126邮箱登录的详细介绍
2013/06/18 PHP
PHP中比较两个字符串找出第一个不同字符位置例子
2014/04/08 PHP
php输出文字乱码的解决方法
2019/10/04 PHP
script标签属性type与language使用选择
2012/12/02 Javascript
JS简单实现登陆验证附效果图
2013/11/19 Javascript
JavaScript中模拟实现jsonp
2015/06/19 Javascript
js制作带有遮罩弹出层实现登录注册表单特效代码分享
2015/09/05 Javascript
jquery实现九宫格大转盘抽奖
2015/11/13 Javascript
基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转
2016/06/12 Javascript
使用bootstrapValidator插件进行动态添加表单元素并校验
2016/09/28 Javascript
详解vue.js2.0父组件点击触发子组件方法
2017/05/10 Javascript
js如何获取网页所有图片
2017/05/12 Javascript
jQuery ajax仿Google自动提示SearchSuggess功能示例
2019/03/28 jQuery
ES6入门教程之let、const的使用方法
2019/04/13 Javascript
vue + typescript + video.js实现 流媒体播放 视频监控功能
2019/07/07 Javascript
解决layui使用layui-icon出现默认图标的问题
2019/09/11 Javascript
Vue 实现从文件中获取文本信息的方法详解
2019/10/16 Javascript
[02:10]DOTA2 TI10勇士令状玩法及不朽Ⅰ展示:焕新世界,如你所期
2020/05/29 DOTA
python计算圆周长、面积、球体体积并画出圆
2014/04/08 Python
python通过字典dict判断指定键值是否存在的方法
2015/03/21 Python
python爬虫实战之爬取京东商城实例教程
2017/04/24 Python
mysql 之通过配置文件链接数据库
2017/08/12 Python
tensorflow 查看梯度方式
2020/02/04 Python
Restful_framework视图组件代码实例解析
2020/11/17 Python
最新pycharm安装教程
2020/11/18 Python
python 生成正态分布数据,并绘图和解析
2020/12/21 Python
为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景
2021/01/05 Python
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
如果让你测试一台高速激光打印机,你都会进行哪些测试
2012/12/04 面试题
建筑结构施工求职信
2014/07/11 职场文书
最美家庭活动方案
2014/08/31 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话全文
2014/10/25 职场文书
Pandas实现DataFrame的简单运算、统计与排序
2022/03/31 Python
Java中的Kotlin 内部类原理
2022/06/16 Java/Android
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript