JavaScript 文件下载,二进制下载,文本下载的几种方式

通过路径来下载文件的三种方式 本文以图片为例

为什么有的时候通过a 标签下载图片直接打开了图片呢?有的时候又是直接下载呢?

  1. 下载直接跳到对应的图片 ? a 标签的地址是外部的,会默认跳转到这个图片 即使设置了 a 的 download 依旧会跳转
  2. 直接下载了图片 图片是本机图片,或者是本域名图片 会直接下载 ;

瞄一眼结构以及对应的地址
在这里插入图片描述

第一种方案直接下载 有局限性

<a href="./005100-1592412660f973.jpg" download="" name="1212312313">本机图片下载</a>
本机图片下载 这个标签的链接为本地图片地址 点击 ‘本机图片下载’ 就可以直接下载

第二种方案 使用canvas 来下载 会比第一种方案好

先说思路在写代码,思路对了才能写出正确的代码
1,应为我们是通过链接下载的图片 先实例化一个 Image,因为 Image 里面有我们所需要的东西 (图片的宽高)
2,创建一个 canvas  通过 JavaScript 的  document.createElement   方法来创建  ,并且创建一个2D的
3,使用 ==canvas  的 drawImage()== 方法来把图片 画上去[drawImage](https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage)
4 , == canvas 的 toDataURL() == 方法返回一个包含图片展示的 data URI  [toDataURL()]('https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toDataURL')
5,还是通过 a 标签来下载图片,在创建一个点击的方法这样 就不用 把创建的 a 追加到页面上去,直接调用方法下载图片即可
    downloadIamge(imgsrc, name = '图片名称') {
      //下载图片地址和图片名
      let image = new Image();
      // 解决跨域 Canvas 污染问题
      image.setAttribute('crossOrigin', 'anonymous');
      image.onload = function () {
        let canvas = document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        let context = canvas.getContext('2d');
        context.drawImage(image, 0, 0, image.width, image.height);
        let url = canvas.toDataURL('image/png'); //得到图片的base64编码数据
        let a = document.createElement('a'); // 生成一个a元素
        let event = new MouseEvent('click'); // 创建一个单击事件
        a.download = name ; // 设置图片名称
        a.href = url; // 将生成的URL设置为a.href属性
        a.dispatchEvent(event); // 触发a的单击事件
      };
      image.src = imgsrc;
    },

第三种方案 通过XMLHttpRequest 来进行下载

1 ,先创建 一个 XMLHttpRequest 并把类型设置为 blob
2, 把请求回来的 blob 的数据通过 URL.createObjectURL 方法转为本地的 blob 路基
3, MouseEvent 创建一个单击事件 执行下载方法

	function dw(url){
			const xhr = new XMLHttpRequest()
				xhr.open('get',url);
				// 把请求类型设置为 blob
				xhr.responseType = 'blob';
				xhr.send();
				xhr.onload = function(sues){
					const data = xhr.response;
					// 把请求回来的blob数据 转为 blob 本地路径 进行下载 这个样不会出现跨域问题
					const imgurl  =URL.createObjectURL(data)
					document.querySelector('#wimgs').src = imgurl
					const elemtA = document.createElement('a');
					// 创建一个 单击事件
					 let event = new MouseEvent('click')
					elemtA.setAttribute('download','');
					elemtA.setAttribute('href',imgurl);
					// 执行单击方法  这里调用此方法就可触发
					elemtA.dispatchEvent(event);	
				}			
		}

内容进行下载,二进制流内容,或者文本内容

应用场景,前端在做报表导出时,后端一般往往是返回的是二进制流的形式

流的方式进行下载

思路

1.下载方式思路跟浏览下载方式是一样的,只不过内容是后端返回的,不是后端生成好返回的链接

2.通过Blob读取后端返回的二进制内容

createObjectURL 创建一个 blob URL进行下载

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取

Blob语法

var aBlob = new Blob( array, options );

参数

  • array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings 会被编码为 UTF-8。

  • options 是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性:

    • type,默认值为 “”,它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
    • endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。 它是以下两个值中的一个: “native”,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 “transparent”,代表会保持 blob 中保存的结束符不变 Non-Standard

代码示例

            const link = document.createElement('a');
            let blob = new Blob(['后端返回的二进制数据'], { type: 'application/vnd.ms-excel' });
            let objectURL = URL.createObjectURL(blob); // 创建URL   blob:https://www.xxx.com/285f734a-0f3a-4f01-b1cc-b95b29d7fd05 此链接可以下载
            link.href = objectURL;
            link.download = '文件名称';
            link.click(); // 调用点击事件,紧张自动点击
            URL.revokeObjectURL(objectURL); // 释放内存

异常处理
由于后端返回的是二进制,后端在生成二进制流错误的时候也会生成二进制的错误流
如:{msg:‘生成错误’,code:200} 此内容也生成二进制,我们需要转为二进制为明文,给与用户提示

使用 TextDecoder

TextDecoder 接口表示一个文本解码器,一个解码器只支持一种特定文本编码,例如 utf-8、iso-8859-2、koi8、cp1261,gbk 等等。解码器将字节流作为输入,并提供代码点流作为输出。
异常处理代码示例

    const enc = new TextDecoder('utf-8');
    const ErrData = enc.decode(new Uint8Array('后端返回二进制错误内容'))

	// 如果是返回内容为对象 需要转化下
    const res = JSON.parse(enc.decode(new Uint8Array('后端返回二进制错误内容'))); //转化成json对象
    console.log(res);

完整代码示例

try {
// 能够解析内容 就为后端生成二进制流错误
  const enc = new TextDecoder('utf-8'), ErrData = enc.decode(new Uint8Array('后端返回二进制错误内容'));

	// 如果是返回内容为对象 需要转化下
    const res = JSON.parse(enc.decode(new Uint8Array(ErrData))); //转化成json对象
   if(res.code === 400){
   	console.log('返回异常')
   }
} catch (error) {
// 解析不出就为正常导出内容
  const link = document.createElement('a');
       let blob = new Blob(['后端返回的二进制数据'], { type: 'application/vnd.ms-excel' });
       let objectURL = URL.createObjectURL(blob); // 创建URL   blob:https://www.xxx.com/285f734a-0f3a-4f01-b1cc-b95b29d7fd05 此链接可以下载
        link.href = objectURL;
        link.download = '文件名称';
        link.click(); // 调用点击事件,紧张自动点击
        URL.revokeObjectURL(objectURL); // 释放内存
}

文本下载

思路
只需要把后端返回的内容替换成,从页面获取的内容即可,注意导出内容格式

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值