前端开发中文件下载和Base64位转化

一、前言

这两天在开发过程中遇到下载图片的需求,没想到常规的写法无法下载,只能在浏览器打开,之前还真没没注意过,思考下最近做的关于文件操作的内容,做下总结。

  • 下载媒体资源
  • 上传媒体(图片、音频、视频)到云存储
  • 本地解析媒体资源
  • Base64位转码给后端保存

二、关于前端文件下载

前端几种常见的下载文件的方法

  • 1、a标签
  • 2、js
  • 3、window.open

需要注意是的,a标签对于跨域的资源是有不同表现的。

  • 当下载资源和当前资源跨域,且当前资源可以直接在浏览器打开预览(比如图片、PDF)将无法下载,会在浏览器打开,解决方法在后面
  • 当下载资源和当前资源跨域,且资源浏览器无法预览(比如XLSX)将会下载该文件
  • 不跨域的情况下将会下载

1、a标签

大部分文件都可以用a标签+download属性来下载,简单方便。

html 复制代码
<a href="path/to/file.pdf" download="filename.pdf">点击下载文件</a>

2、js下载文件

js下载文件也是通过创建a标签来实现的,对比a标签的下载更灵活。

js 复制代码
export const downloadFile = ({
    fileUrl, 
    fileName, 
    callback
}:{
    fileUrl: string,
    fileName: string,
    callback?: (error?:any) => void
}) => {
  try {
    const url = fileUrl;
    const link = document.createElement('a');
    link.target = '_blank';
    link.style.display = 'none';
    link.href = url;
    link.setAttribute('download', fileName);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    callback && callback();
  } catch (err) {
    callback && callback(err);
  }
};

因为JS也是通过创建A标签来实现的,所以需要先拉取Blob格式的资源,然后创建本地域名一致的资源URL,再进行下载

js 复制代码
export const downloadCorsFile = ({
    fileUrl, 
    fileName, 
    callback
}:{
    fileUrl: string,
    fileName: string,
    callback?: (error?:any) => void
}) => {
  try {
    // 也可以使用fetch拉取资源,不过要注意兼容性
    const xhr = new XMLHttpRequest();
    xhr.open('get', fileUrl, true);
    xhr.responseType = 'blob';
    xhr.send();
    xhr.onload = function (res) {
      const url = window.URL.createObjectURL(res.target.response);
      downloadFile({url, fileName, callback});
    };
  } catch (err) {
    callback(err);
  }
};

3、利用浏览器行为下载

window.openwindow.location.href是利用浏览器对应的URL就会将文件下载下来。可以用来下载XLSX、ZIP文件等。

js 复制代码
window.open('https://demo/download_filename.xlsx', '_blank')
window.location.href = 'https://demo/download_filename.xlsx'

三、文件转化成Base64位

1、File或Blob类型转化成base64位

在开发中,我们常常要将文件转化成base64位,文件可能是手动上传的文件、通过URL下载的图片等。

原理都是通过FileReader对象,调用实例方法readAsDataURL将文件读取为Base64位。

js 复制代码
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
  const result = reader.result;
}

由于异步获取的base64位,为了方便使用,我们常常通过Promise处理下

js 复制代码
// File/Blob转化成base64位
export function fileToBase64(file: File | Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onloadend = () => {
      const result = reader.result;
      resolve(result);
    };
    reader.onerror = reject;
  });
}

2、通过URL获取文件的类型,然后将Blob转化成base64位

js 复制代码
export function urlToBase64(url) {
  return fetch(url)
    .then((response) => response.blob())
    .then((blob) => {
      return fileToBase64(blob)
    });
}

FileReader对象的几种常见方法包括:

  • readAsBinaryString(Blob or File):将输入的 Blob 或 File 对象读取为二进制字符串。
  • readAsArrayBuffer(Blob or File):将输入的 Blob 或 File 对象读取为一个 ArrayBuffer。
  • readAsDataURL(Blob or File):将输入的 Blob 或 File 对象读取为一个 Base64 编码的字符串。
  • readAsText(Blob or File, encoding):将输入的 Blob 或 File 对象读取为一个文本字符串,其中第二个参数指定字符编码。
相关推荐
小桥风满袖31 分钟前
极简三分钟ES6 - ES8中字符串扩展
前端·javascript
张拭心31 分钟前
这就是流量的力量吗?用豆包 AI 编程做的xhs小组件帖子爆了
前端·ai编程·豆包marscode
少年阿闯~~35 分钟前
CSS3的新特性
前端·javascript·css3
IT_陈寒41 分钟前
React性能优化:这5个Hook技巧让我的组件渲染效率提升50%(附代码对比)
前端·人工智能·后端
智能化咨询1 小时前
【Linux】【实战向】Linux 进程替换避坑指南:从理解 bash 阻塞等待,到亲手实现能执行 ls/cd 的 Shell
前端·chrome
Anson Jiang1 小时前
浏览器标签页管理:使用chrome.tabs API实现新建、切换、抓取内容——Chrome插件开发从入门到精通系列教程06
开发语言·前端·javascript·chrome·ecmascript·chrome devtools·chrome插件
掘金安东尼1 小时前
黑客劫持:周下载量超20+亿的NPM包被攻击
前端·javascript·面试
剑亦未配妥2 小时前
移动端触摸事件与鼠标事件的触发机制详解
前端·javascript
人工智能训练师8 小时前
Ubuntu22.04如何安装新版本的Node.js和npm
linux·运维·前端·人工智能·ubuntu·npm·node.js