JS中Blob与FileReader

Blob :(Binary Large Object)二进制大对象

Bold是一个专门支持文件的二进制对象,用来支持文件操作

Blob构造函数接受两个参数,

  • 参数一: 字符串或二进制对象
  • 参数二: 一个配置项 对象 {}

参数二目前只有一个type属性, 值是字符串, 标识数据的MIME类型,(默认值是空字符串)
列: new Blob([ 'b' ]) // => {size: 2, type: ""}

size: 字节数(大小)。
type: 类型。(会在下文详细解说)

创建一个Blob,查看其原型提供的方法

blob.png

其中:

arrayBuffer: 读和写,用来表示通用的、固定长度的原始二进制数据缓冲区,你不能直接操作 ArrayBuffer 的内容,而是要通过类型数组对象DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
slice: 切割blob对象,(可实现分片上传等)slice(start, end)
text: 会返回一个(期约)promise对象,包含了blob的内容,使用UTF-8的编码来解析
stream:
在MDN有详细的解说 / 点击跳转

文件流下载

AJAX 请求时,如果指定responseType属性为blob,下载下来的就是一个 Blob 对象。
列:

function getAxiosBlob() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', url);
  xhr.responseType = 'blob';
  xhr.send();
}

我们可以通过window.URL.createObjectURL,接收一个Blob(File)对象,将其转化为Blob URL,方便某些API使用,这些URL以blob:开头,标识这是一个blob文件


bloba.png

实际使用中:会配合a标签的download属性配合下载

axios.get(imageUrl, {
    headers: {
      'Authorization': token,
    },
    responseType: 'blob', // axios 添加blob type
  })
.then((respone) => {
          let resData = response.data
          // new Blob() 对返回的文件流类型处理
          const blob = window.URL.createObjectURL(new Blob([resData], { type: 'application/ms-excel'}));
          //   生成一个a元素
          let a = document.createElement('a')
          // 创建一个单击事件
          let event = new MouseEvent('click')
          // 图片名称
          a.download = '订单数据报表' + new Date().getTime() + '.xlsx' // 默认的名称
          // 将生成的URL设置为a.href属性
          a.href = blob
          a.dispatchEvent(event)
})

img 显示blob图片

window.URL.createObjectURL,的URL还可以赋值给img.src 进行图片的显示

    <div class="sss">
        <input id="pictrue" type="file" accept="*/image">
    </div>
    <script>
        let inputpic = document.querySelector('#pictrue')
        let sss = document.querySelector('.sss')
        inputpic.addEventListener('change', function(e) {
            let file = this.files[0]
            let url = window.URL.createObjectURL(new Blob([file]))
            let im = document.createElement('img')
            im.src = url
            sss.appendChild(im)
        })
    </script>

4、文件分片


fp2.png

在这里我们可以看到 ,上传图片在其中的原型上有Blob对象,意味着我们可以直接使用Blob的方法,(这里的示例还是用上面的代码)(切割主要用到slice)

    <div class="sss">
        <input id="pictrue" type="file" accept="*/image">
    </div>
    <script>
       let inputpic = document.querySelector('#pictrue')
        let sss = document.querySelector('.sss')
        let arrupload = []
        inputpic.addEventListener('change', function(e) {
            let fileblob = this.files[0]
            const end = fileblob.size
            const chunk = 2000
            let start = 0
            while (start < end) {
                arrupload.push(fileblob.slice(start, start + chunk))
                // 实际使用中应直接使用下面的方法 直接调用接口上传bolb对象, 我现在这里把每个blob对象打印处理方便大家看到
                // uploadFn(fileblob.slice(start, start + chunk))
                start = start + chunk
            }
            console.log(fileblob.size)
            console.log(arrupload)
        })
</script>
blobupload.png

在这里可以看, 文件被分成了46份

读取文件

FileReader()
想要读取Blob或者文件对象并转化为其他格式的数据,可以借助FileReader对象的API进行操作

FileReader.readAsText(Blob):将Blob转化为文本字符串
FileReader.readAsArrayBuffer(Blob): 将Blob转为ArrayBuffer格式数据
FileReader.readAsDataURL(): 将Blob转化为Base64格式的Data URL

使用例子

          const reader = new FileReader()
          reader.readAsText(response.data) // 以text文本显示
          reader.onload = function(event) {
            const { message } = JSON.parse(reader.result)
            Massage.info(message) // 将错误信息显示出来
          }

补充:MIME类型

用来表示 文件流/文档 用什么格式
浏览器用何种形式来处理URL
常见类型有
txt text/plain
doc application/msword
exe application/octet-stream
pdf application/pdf
ps application/postscript
xlm application/vnd.ms-excel
xls application/vnd.ms-excel
ppt application/vnd.ms-powerpoint
gz application/x-gzip
zip application/zip
mp3 audio/mpeg
wav audio/x-wav
bmp image/bmp
gif image/gif
jpe image/jpeg
jpeg image/jpeg
jpg image/jpeg
mpg video/mpeg
mov video/quicktime

使用场景:

前端请求后端的时候返回一个流文件,这时候可以判断流文件的类型, 来做出正确的处理

export const downloadEcxel = (imageUrl, name) => {
  const token = store.getState().user.tokenHead +  store.getState().user.token
  axios.get(imageUrl, {
    headers: {
      'Authorization': token,
    },
    responseType: 'blob', // axios 添加blob type
  })
    .then(function(response) {
      if (response.status >= 200 || response.status <= 300) {
        let resData = response.data
        if (resData.type === 'application/json') {
          // 将blob文件流转换成json
          const reader = new FileReader()
          reader.readAsText(response.data) // 以text文本显示
          reader.onload = function(event) {
            const { code, message } = JSON.parse(reader.result)
            console.log(message) // 将错误信息显示出来
          }
        } else {
          // new Blob() 对返回的文件流类型处理
          const blob = window.URL.createObjectURL(new Blob([resData], { type: 'application/ms-excel'}));
          console.log(blob)
          //   生成一个a元素
          let a = document.createElement('a')
          // 创建一个单击事件
          let event = new MouseEvent('click')
          // 图片名称
          a.download = '订单数据报表' + new Date().getTime() + '.xlsx' // 默认的名称
          // 将生成的URL设置为a.href属性
          a.href = blob
          a.dispatchEvent(event)
        }
      } else {
        console.log('下载失败')
      }
    })
    .catch(function(error) {
      console.log(error);
    });
}

有不对的大家可以留言,看到会回复

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容