JS基础:下载文件

389 阅读3分钟

前言

最近写项目时遇到了向后台请求下载文件时,返回传输文件格式为二进制流的情况。正好借此机会了解文件二进制上传/下载

Blob 对象

Blob 对象表示一个不可变的, 原始数据的类似文件对象,可以作为二进制文件存放的容器

可以通过构造函数来构建 Blob 对象

var blob = new Blob(array[optional], options[optional]);
// 第一个参数:数据序列,可以是任意格式的值,
// 例如,任意数量的字符串,Blob 以及 ArrayBuffers
// 第二个参数:用于指定将要放入Blob中的数据的类型

Blob 对象的基本属性:

  • size :Blob 对象包含的字节数(只读)
  • type :Blob 对象包含的数据类型,如果类型未知则返回空字符串。

上传

通过 formData 对象实现异步上传二进制文件

创建一个空 FormData 对象,向 FormData 对象中添加文件对应的键/值对

var formData = new FormData();
formdata.append('file', upload_file)

创建负载 formData 对象的请求发送至服务器,服务器收到 formData 对象后为其开辟空间。

下载

文件二进制流转文件下载的方法:

  1. 通过 fileReader 对象实现异步读取二进制文件
  2. 通过 Blob 对象和 msSaveBlob(blob, fileName) 以本地方式保存文件
  3. 通过 createObjectURL 把 Blob 对象指向到一个 URL, 再赋予到a标签

通过 fileReader 对象实现异步读取二进制文件

向服务器发送返回类型 Blob 对象的请求,并获取到文件的二进制 Blob 对象。

// headerconfig
xhr.responsetype = blob;

创建 FileReader 对象读取 Blob 对象,并通过a标签下载。

let reader = new FileReader();  
reader.readAsDataURL(Blob); // 转换为base64,直接放入a标签href  
reader.onload = function(e) {  
    // 转换完成,创建一个a标签用于下载  
    let a = document.createElement('a');  
    a.download = fileName;  
    a.href = e.target.result;  
    document.body.appendChild(a); // 修复firefox中无法触发click  
    a.click();  
    document.body.removeChild(a);
}

通过 Blob 对象和 msSaveBlob(blob, fileName) 以本地方式保存文件

向服务器发送返回类型 Blob 对象的请求,并获取到文件的二进制 Blob 对象。

// headerconfig
xhr.responsetype = blob;

通过 Blob 对象和 msSaveBlob(blob, fileName) 以本地方式保存文件

if (window.navigator.msSaveOrOpenBlob) {  
    navigator.msSaveBlob(blob, fileName);  
}

通过 createObjectURL 把 Blob 对象指向到一个 URL, 再赋予到a标签

向服务器发送返回类型 Blob 对象的请求,并获取到文件的二进制 Blob 对象。

// headerconfig
xhr.responsetype = blob;
function downloadWithLink(blob, fileName) {
    objectUrl = window.URL.createObjectURL(blob) // 创建新的 url 表示指定 Blob 对象
    a = document.createElement('a') // 创建 a 标签
    a.href = objectUrl指定下载链接
    a.download = fileName // 指定下载文件名
    a.click() // 触发下载
    a.remove() // 移除 a 标签
    window.URL.revokeObjectURL(objectUrl) // 释放
}
function downloadWithLink(dataUrl, fileName) {
  let link = document.createElement('a')
  link.href = dataUrl
  link.download = fileName
  link.click()
  link = null
}

图片 url 转 base64Url

export const createCanvasToDataUrl = (img?, type?) => {
  let canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  canvas.height = img.height
  canvas.width = img.width
  ctx.drawImage(img, 0, 0)
  const dataUrl = canvas.toDataURL(`image/${type || 'jpeg'}`)
  canvas = null
  return dataUrl
}

file-saver 前端下载利器

两种上传场景

一种是在表单提交时,直接携带文件本体,这样效率会比较低

另外一种是提供一个接口,用于给文件上传换取 url,在表单提交时携带换取后的 url。

参考资料

JS : Blob() 转换二进制下载文件流实例(CSDN论坛)

JavaScript 中 Blob 对象(掘金网)