添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
·  阅读 浏览器端文件操作 file base64 blob ArrayBuffer

前端要在浏览器中操作一些文件,这里记录一下常用相互转换的方法,比如file base64 blob ArrayBuffer之间的相互转换。并且记录一些常用转换文件的方法

转 file

base64 转 file

// 此方法需要base64头部信息,文件名不需要扩展名。适用图片、pdf文件、txt文件。
// 通过 fileToBase64 转换的,带头部信息
const dataUrlToFile = function (urlData, filename) { // 64转file
  if (typeof urlData != 'string' || !filename) {
    console.log("参数不正确")
    return;
  const [u8arr, type] = dataUrlToBuffer(urlData)
  const fileExt = type.split('/')[1]
  return new File([u8arr], `${filename}.${fileExt}`, {
    type: type
// 一个文件的纯base64,无头部信息,文件格式需要指定,文件名需要带上扩展名。普遍适用
const base64ToFile = function (base64, filename, type) {
  if (typeof base64 != 'string' || !filename || !type) {
    console.log("参数不正确")
    return;
  const u8arr = base64ToBuffer(base64)
  return new File([u8arr], filename, {
    type: type

这种方法获取的base64缺少头部,当需要头部的时候需要加上,比如

  • jpg图片:data:image/jpeg;base64,
  • png图片:data:image/png;base64,
  • excel文件:data:application/vnd.ms-excel;base64,
  • txt文件:data:text/plain;base64,
  • word文件:data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,
  • pdf文件:data:application/pdf;base64,
  • blob 转 file

    const blobToFile = (blob, fileName, options = {}) => {
        return new File([blob], fileName, options)
    

    ArrayBuffer 转 file

    const arrayBufferToFile = blobToFile
    

    转base64

    file 转 base64

    转换后带有头部信息

    const fileToBase64 = (file) => {
        return new Promise((resolve) => {
            const reader = new FileReader()
            reader.onload = function(result) {
                resolve(result.target.result)
            reader.readAsDataURL(file)
    

    blob 转 base64

    转换后带有头部信息

    const blobToBase64 = fileToBase64
    

    ArrayBuffer 转 base64

    转换后没有头部

    const arrayBufferToBase64 = (buffer) => {
        return window.btoa(String.fromCharCode(...new Uint8Array(buffer)))
    

    转换后没有头部

    function arrayBufferToBase64 (buffer) {
        let binary = '';
        const bytes = new Uint8Array(buffer);
        for (let len = bytes.byteLength, i = 0; i < len; i++) {
            binary += String.fromCharCode(bytes[i]);
        return window.btoa(binary);
    

    转 blob

    file 转 blob

    const fileToBlob = (file, type = '') => {
        return new Blob([file],{ type:'image/png' })
    fileToBlob(file, 'image/png')
    

    base64 转 blob

    // 带头部的base64(dataUrl)
    const dataUrlToBlob = (dataURI) => {  
        const [u8arr, type] = dataUrlToBuffer(dataURI)
        return new Blob([u8arr], {type})
    
    // 纯base64,需要指定类型,比如 text/plain,取`data:xxxxxx;base64,` xxx部分
    const base64ToBlob = (base64, type = '') => {
        const u8arr = base64ToBuffer(base64) 
        return new Blob([ab], {type})
    

    ArrayBuffer 转 blob

    const arrayBufferToBlob = fileToBlob
    

    转 ArrayBuffer

    file 转 ArrayBuffer

    const fileToArrayBuffer = (file) => {
        return new Promise((resolve) => {
            let reader = new FileReader()
            reader.onload = function(result) {
                resolve(result.target.result)
            reader.readAsArrayBuffer(file)
    

    base64 转 ArrayBuffer

    const base64ToBuffer = (base64String) => {
        const padding = '='.repeat((4 - base64String.length % 4) % 4);
        const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');
        const rawData = window.atob(base64);
        const outputArray = new Uint8Array(rawData.length);
        for (let i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i);
        return outputArray;
    const dataUrlToBuffer = (urlData) => {
        const [head, base64] = urlData.split(',')
        const type = head.match(/:(.*?);/)[1]
        return [base64ToBuffer(base64), type]
    

    blob 转 ArrayBuffer

    const blobToArrayBuffer = fileToArrayBuffer
    
  • base64在转成其他类型之前首先要转换成ArrayBuffer
  • DataURL&ObjectURL
  • 其中mediatype是表示MIME类型的字符串,默认值为"text/plain;charset=US-ASCII"
  • BlobURL的格式是blob:域名/uuid,需要先将其他格式转换成file或者blob。
  • DataURL的格式是data:[[;base64],
  • 前者长度往往更短,因为后者的数据中存储着图片的base64编码
  • 我们可以直接将DataURL复制到浏览器地址栏进行访问,但BlobURL则不能
  • canvas 转图片

    // canvas.toDataURL 返回的是一串Base64编码的URL
    // PND:image/png    jpg:image/jpeg
    const missionImg = document.getElementById('canvas').toDataURL('image/png', 1.0);
    
    var a = document.createElement('a');
    a.download = '文件.jpg';  //下载的文件名,默认是'下载'
    a.href = missionImg; 
    document.body.appendChild(a);
    a.click();
    a.remove();  //下载之后把创建的元素删除
    

    当canvas中画了一个跨域图片进去的时候最好是把文件转换成base64再去画图,防止使用toDataURL的时候跨域

    作为图片显示

    const image = new Image();
    image.src = missionImg;
    $('#img').append(img);
    

    axios读取文件(小心跨域)

    当遇到跨域的时候需要通过服务端处理(接口返回、nginx反向代理),推荐接口返回能安全的很

    try {
        // 读取的文件是字符串类型
        // 请求头 response 中 { responseType: 'arraybuffer'}
        // 请求文本文件的时候responseType为空,或者 text,也不需要转化为blob
        const res = await axios.get(fileUrl, {responseType: 'arraybuffer'});
        // 转换为blob方便后续操作
        const blob = new Blob([res.data]);
    } catch (error) {
        console.log(error, '获取文件失败');
    

    直接获取blob

    try {
        // 请求头中 response 的类型 { responseType: 'blob'}
        const res = await axios.get(fileUrl, {responseType: 'blob'});
        const blob = res.data;
    } catch (error) {
        console.log(error, '获取文件失败');
    

    转化为url并下载

    var a = document.createElement('a');
    var fileurl = URL.createObjectURL(blob)
    var a = document.createElement('a');
    a.download = 'filename.xls';
    a.href = fileurl;
    a.click();
    URL.revokeObjectURL(fileurl);
    

    js-xlsx 读取Excel文件

    try {
        const res = await axios.get(fileUrl, {responseType: 'blob'});
        const blob = res.data;
        const fileReader = new FileReader();
        fileReader.onload = (ev) => {
            const data = ev.target.result;
            //console.log(data)
            const workbook = XLSX.read(data, {type: 'binary'});
            console.log(workbook.Sheets);
            for (const sheet in workbook.Sheets) {
                console.log(sheet);
                if (!workbook.Sheets.hasOwnProperty(sheet)) continue;
                const fromTo = workbook.Sheets[sheet]['!ref'];
                console.log(fromTo);
                const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
                console.log(data);
        fileReader.readAsBinaryString(blob);
    } catch (error) {
        console.log(error);
        this.$nav.error('解析文件失败!');
    

    PDF的相关操作

    浏览器html代码生成图片保存为PDF并上传 - 掘金 (juejin.cn)

    js一张图搞定arrayBuffer/Blob/File/fileReader/canvas/base64的各种转换操作,以及文件上传 - 掘金 (juejin.cn)

  • FileReader - Web API 接口参考 | MDN (mozilla.org)
  • WindowOrWorkerGlobalScope.atob() - Web API 接口参考 | MDN (mozilla.org)
  • URL.createObjectURL() - Web API 接口参考 | MDN (mozilla.org)
  • URL.revokeObjectURL() - Web API 接口参考 | MDN (mozilla.org)
  • XMLHttpRequest.responseType - Web API 接口参考 | MDN (mozilla.org)
  • Blob - Web API 接口参考 | MDN (mozilla.org)
  • Uint8Array - JavaScript | MDN (mozilla.org)
  • JS 文件base64、File、Blob、ArrayBuffer互转 - SegmentFault 思否
  • Blob、File、ArrayBuffer对象文件流_TianNicholas的博客-CSDN博客_arraybuffer 文件流
  • ArrayBuffer转base64详解 - 陌上兮月 - 博客园 (cnblogs.com)
  • Blob、File、ArrayBuffer对象文件流_TianNicholas的博客-CSDN博客_arraybuffer 文件流
  • (JavaScript) base64 字符串 和 ArrayBuffer 之间转换 - 橘子味儿的猫 - 博客园 (cnblogs.com)
  • 分类:
    前端
    标签: