JavaScript 实现 Base64 文件处理与下载完整指南

作者:纸飞机

时间:2026-10-31

浏览:555

本文详解 JavaScript 中 Base64 数据的完整处理流程,涵盖从拼接完整 Base64 地址到转换为 Blob 和 File 对象的方法。重点解析图片与普通文件的下载实现,包括 Canvas 绘图下载及普通文件流处理,并提供基于 JSZip 的批量文件打包下载方案,帮助开发者解决前端文件导出难题。

文章目录

首先,需要获取完整的 Base64 地址。在实际开发中,后端返回的数据往往不包含 Base64 的前缀信息,因此需要在前端根据文件类型拼接完整的前缀。例如,通过调用接口获取文件类型和原始数据,然后利用 `getBase64Type` 函数根据后缀名(如 txt、png、jpg 等)返回对应的 `data:image/xxx;base64,` 前缀,将其与后端返回的数据拼接,从而形成完整的 Base64 字符串。

//获取后端返回的不完成base64、文件名、文件类型
function downladBase64(item) {
    APINAME().then((res) => {
            let base64 = getBase64Type(res.data.fileType) + res.data.data //类型拼接后端给的不完整base64
            console.log('拼接完整的base64', base64)
            downloadFileByBase64(base64, res.data.fileName)
    })
}

//根据文件后缀 获取base64前缀不同 拼接完整的base64
function getBase64Type(type) {
    switch (type) {
        case 'txt':
            return 'data:text/plain;base64,'
        case 'doc':
            return 'data:application/msword;base64,'
        case 'docx':
            return 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,'
        case 'xls':
            return 'data:application/vnd.ms-excel;base64,'
        case 'xlsx':
            return 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,'
        case 'pdf':
            return 'data:application/pdf;base64,'
        case 'pptx':
            return 'data:application/vnd.openxmlformats-officedocument.presentationml.presentation;base64,'
        case 'ppt':
            return 'data:application/vnd.ms-powerpoint;base64,'
        case 'png':
            return 'data:image/png;base64,'
        case 'jpg':
            return 'data:image/jpeg;base64,'
        case 'gif':
            return 'data:image/gif;base64,'
        case 'svg':
            return 'data:image/svg+xml;base64,'
        case 'ico':
            return 'data:image/x-icon;base64,'
        case 'bmp':
            return 'data:image/bmp;base64,'
    }
}

接下来,将完整的 Base64 字符串转换为 Blob 对象。这一过程通过 `dataURLtoBlob` 函数实现,该函数首先解析 Base64 字符串,提取 MIME 类型,然后使用 `atob` 方法将 Base64 解码为二进制字符串。接着,创建一个 `Uint8Array` 数组,将二进制字符串的每个字符编码转换为对应的字节值,最后封装为 `Blob` 对象并返回。这一步是后续下载操作的基础。

//将完整的base64转换为blob
function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
    }
    return new Blob([u8arr], { type: mime })
}

此外,有时需要将 Base64 数据直接转换为 File 对象。`base64ImgtoFile` 函数实现了这一功能,它接收 Base64 字符串和文件名作为参数。函数内部同样解析 MIME 类型和后缀名,解码 Base64 数据并构建 `Uint8Array`,最后使用 `File` 构造函数创建文件对象。该函数支持异步操作,并包含错误处理机制,确保在转换失败时能抛出异常。

// 将base64转换为文件
export default async function base64ImgtoFile(dataurl, filename = 'file') {
    try {
        const arr = dataurl.split(',')
        const mime = arr[0].match(/:(.*?);/)[1]
        const suffix = mime.split('/')[1]
        const bstr = atob(arr[1])
        let n = bstr.length
        const u8arr = new Uint8Array(n)
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], `${filename}.${suffix}`, {
            type: mime
        })
    } catch (err) {
        return Promise.reject(err);
    }
}

实现 Base64 文件的下载功能,核心在于将 Base64 数据转换为可下载的 URL。`downloadFileByBase64` 函数作为下载入口,首先调用 `dataURLtoBlob` 将 Base64 转换为 Blob 对象,然后使用 `URL.createObjectURL` 生成一个指向该 Blob 的临时 URL。最后,调用 `downloadFile` 函数,利用该 URL 触发浏览器的下载行为。

// * desc: 下载参数入口
// * @param base64  :返回数据的blob对象或链接
// * @param fileName  :下载后文件名标记
function downloadFileByBase64(base64, fileName) {
    var myBlob = dataURLtoBlob(base64)
    var myUrl = URL.createObjectURL(myBlob)
    downloadFile(myUrl, fileName)
}
// * desc: 下载方法
// * @param url  :返回数据的blob对象或链接
// * @param fileName  :下载后文件名标记
function downloadFile(url, name = "What's the fuvk") {
    console.log('url==', url)
    var a = document.createElement("a")
    a.setAttribute("href", url)
    a.setAttribute("download", name)
    a.setAttribute("target", "_blank")
    let clickEvent = document.createEvent("MouseEvents")
    clickEvent.initEvent("click", true, true)
    a.dispatchEvent(clickEvent)
}
export default downloadFileByBase64

针对图片文件的下载,通常采用 Canvas 绘图的方式。`downloadImage` 函数创建一个 `Image` 对象,设置跨域属性以支持跨域图片。在图片加载完成后,将图片绘制到动态创建的 Canvas 元素上,并通过 `canvas.toDataURL` 生成新的 Base64 数据。随后,创建一个隐藏的 `<a>` 标签,设置其 `href` 为生成的数据 URL,并触发点击事件,从而触发图片下载。

export const downloadImage = (imgsrc, name) => { // 下载图片地址和图片名
  var image = new Image()
  image.setAttribute('crossOrigin', 'anonymous')
  image.onload = function() {
    var canvas = document.createElement('canvas')
    canvas.width = image.width
    canvas.height = image.height
    var context = canvas.getContext('2d')
    context.drawImage(image, 0, 0, image.width, image.height)
    var url = canvas.toDataURL('image/png') // 得到图片的base64编码数据

    var a = document.createElement('a') // 生成一个a元素
    var event = new MouseEvent('click') // 创建一个单击事件
    a.download = name || 'photo' // 设置图片名称
    a.href = url // 将生成的URL设置为a.href属性
    a.dispatchEvent(event) // 触发a的单击事件
  }
  image.src = imgsrc
}

对于普通文件(如文档、压缩包等)的下载,流程相对直接。在获取到完整的 Base64 数据后,先将其转换为 Blob 对象,再生成临时 URL。通过创建一个隐藏的 `<a>` 标签,设置其 `href` 为临时 URL 和 `download` 属性为目标文件名,最后模拟鼠标点击事件,即可触发浏览器的文件下载对话框,完成文件保存。

/**
 * 下载文件
 *
 * @param {*} path 下载地址/下载请求地址。
 * @param {string} [name='name.jpg'] 下载文件的名字(考虑到兼容性问题,最好加上后缀名
 */
export const downloadFile = (path, name = 'name.jpg') => {
        const download = (href) => {
            const a = document.createElement('a')
            a.style.display = 'none'
            a.href = href
            a.download = name
            document.body.appendChild(a)
            a.click()
            document.body.removeChild(a)
        }

        if (isIE()) {
            download(path)
        } else {
            const xhr = new XMLHttpRequest()
            xhr.open('get', path)
            xhr.responseType = 'blob'
            xhr.send()
            xhr.onload = (e) => {
                const { status, response } = e.target
                if (status === 200 || status === 304) {
                    const fileReader = new FileReader()
                    fileReader.readAsDataURL(response)
                    fileReader.onload = (ev) => {
                        download(ev.target.result)
                    }
                }
            }
        }
    }
    // 判断是否IE
export function isIE() {
    return /msie|trident/.test(window.navigator.userAgent.toLowerCase())
}

如果需要批量下载多个文件并导出为 ZIP 格式,可以使用 `JSZip` 库。该方案遍历需要下载的文件列表,对每个文件执行上述 Base64 转 Blob 并添加至 ZIP 包的步骤。所有文件添加完毕后,生成 ZIP 文件的 Blob 数据,生成临时 URL,并通过触发 `<a>` 标签的点击事件,实现单个 ZIP 文件的下载。这种方式有效解决了前端批量导出文件的难题。

import JSZip from 'jszip'
import FileSaver from 'file-saver'
import axios from 'axios'
// 批量导出
function getFile(url) {
    return new Promise((resolve, reject) => {
        axios({
            method: 'get',
            url,
            responseType: 'arraybuffer'
        }).then(data => {
            resolve(data.data)
        }).catch(error => {
            console.log(error, url, 'getfile-err')
                // reject(error.toString());
            resolve('')
        })
    })
}

/**
 * 
 * @param {Array} files 需要下载的文件对象数组[{name,url}]
 * @param {String} zipName 压缩包名称
 * @param {Function} callback 下载完成后的回调
 */
function batchDownZip(files, zipName, callback) {
    const data = files
    const zip = new JSZip()
    const cache = {}
    const promises = []
    data.forEach(item => {
        // console.log(getFile, 'getFile')
        const promise = getFile(item.url).then(result_file => { // 下载文件, 并存成ArrayBuffer对象
            let file_name = item.name // 获取文件名
            let lastIndex = file_name.lastIndexOf('/')
            console.log(result_file, file_name, lastIndex, 'result_file111')
                //将所有文件放入同一级
            if (lastIndex > -1) {
                file_name = file_name.slice(lastIndex + 1)
            }
            console.log(result_file, file_name, lastIndex, 'result_file222')

            zip.file(file_name, result_file, { binary: true }) // 逐个添加文件
            cache[file_name] = data
        })
        promises.push(promise)
    })
    Promise.all(promises).then(() => {
        zip.generateAsync({ type: 'blob' }).then(content => {
            // 生成二进制流
            FileSaver.saveAs(content, zipName) // 利用file-saver保存文件  自定义文件名
            callback && callback()
        })
    })
}

export default batchDownZip

综上所述,JavaScript 处理 Base64 文件并实现下载的核心在于数据的正确转换与 URL 的生成。通过拼接完整 Base64、转换为 Blob 或 File 对象,并利用 Canvas 或隐藏链接触发下载,可以灵活应对图片、普通文件及批量打包下载的需求。掌握这些方法,能够显著提升前端文件处理的能力。

到此这篇关于 js 实现 base64 文件的处理以及下载方法的文章就介绍到这了,更多相关 js base64 文件处理下载内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章