前端下载文件或者图片方式,window.open或者a标签形式

这篇具有很好参考价值的文章主要介绍了前端下载文件或者图片方式,window.open或者a标签形式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先分别讲一下下载文件的方式都有哪些

1.通过a标签的方式下载文件

<a href="http://www.baidu.com" download="baidu.html">下载</a>

我们点击下载,发现是跳转到了百度的首页,并没有真的下载文件。

因为a标签下载只能下载同源的文件;如果是跨域的文件,比如图片、音视频等媒体文件等都无法使用上面的a标签方式下载。

上面的代码是直接通过书写a标签来实现文件下载;我们也可以通过js来实现,代码如下:

const a = document.createElement('a')
a.href = 'http://www.baidu.com'
a.download = 'baidu.html'
a.click()

效果和上面的一样,都是跳转到百度的首页,没有下载文件。

这里的重点是a标签的download属性,这个属性是HTML5新增的。

它的作用是指定下载的文件名,如果不指定,那么下载的文件名就会根据请求内容的Content-Disposition来确定,如果没有Content-Disposition,那么就会使用请求的URL的最后一部分作为文件名。

2. 使用 window.open 下载

上面使用a标签的案例也可以通过window.open来实现,效果是一样的,代码如下:

window.open('http://www.baidu.com', '_blank')

这里的_blank是指定用浏览器新窗口打开链接;如果不指定,那么就会在当前页面打开。

同样a标签的download属性也是可以使用的,代码如下:

window.open('http://www.baidu.com', '_blank', 'download=baidu.html')

当然这种方式也是有缺陷的,对比于a标签,window.open方式不能下载.html.htm.xml.xhtml等文件;因为这些文件会被当成html文件来处理,所以会直接在当前页面打开。

同样也不能下载跨域的文件,这个是window.open 实现下载原理决定的。

3. XMLHttpRequest

这种方式就是我们常说的ajax下载,包括AxiosFetch等,代码如下:

const xhr = new XMLHttpRequest()
xhr.open('GET', 'http://www.baidu.com')
xhr.send()
 
xhr.onload = function () {
  const blob = new Blob([xhr.response], { type: 'text/html' })
  const a = document.createElement('a')
  a.href = URL.createObjectURL(blob)
  a.download = 'baidu.html'
  a.click()
}

这里关于XMLHttpRequest相关的知识就不做展开了,只讲和文件下载相关的部分。

上面代码主要的逻辑是当我们的请求成功后,我们会拿到响应体Response,这个Response就是我们要下载的内容。

然后我们把它转换成Blob对象,通过URL.createObjectURL来创建一个URL,最后使用a标签的download属性来实现文件下载。

4.Blob 对象

下面是MDN对Blob对象的定义:

Blob对象表示一个不可变、原始数据的类文件对象。

Blob的数据可以按文本或二进制的格式进行读取,也可以转换成ReadableStream来用于数据操作。

Blob表示的不一定是JavaScript原生格式的数据。

File接口基于Blob,继承了Blob的功能并将其扩展以支持用户系统上的文件。

Blob对象是html5新增的对象,它的作用是用来存储二进制数据的,比如图片、视频、音频等,它的使用方法如下:

/**
 * @param {Array} array 二进制数据
 * @param {Object} options 配置项
 * @param {String} options.type 文件类型,它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
 * @param {String} options.endings 用于指定包含行结束符\n的字符串如何被写入。默认为transparent,表示不会修改行结束符。还可以指定为native,表示会将\n转换为\r\n。
 */
const blob = new Blob([], { type: '' })

Tips:需要关注的是type属性,默认情况下, Blob对象是没有type属性的,那么这个Blob就是一个无类型的Blob ,文件不会损毁,但是无法被正常识别。

5.URL.createObjectURL

下面是MDN对 URL.createObjectURL方法的定义: 

URL.createObjectURL()静态方法会创建一个DOMString,其中包含一个表示参数中给出的对象的URL。

这个URL的生命周期和创建它的窗口中的document绑定。

这个新的URL对象表示指定的File对象或Blob对象。

这个方法是用来创建一个URL的,它的作用是把一个Blob对象转换成一个URL,这个URL可以用来下载文件,也可以用来预览文件,代码如下:

const url = URL.createObjectURL(blob)

这里需要注意的是,这个URL的生命周期和创建它的窗口中的document绑定。

也就是说,当我们的document被销毁后,这个URL就会失效,所以我们需要在合适的时机销毁它。

代码如下:

URL.revokeObjectURL(url)

回到我们刚才下载的问题,我们是通过Blob对象来解决,但是我们的type属性是写死的,如果在文件类型是确定的情况下是没问题的。

但是如果这个接口就是下载文件的接口,文件可能是各种类型的,我们应该怎么处理?

这里的没有正确答案,第一个可以和接口提供者进行协商,协商方案是不确定的;第二就是通过Response的header来获取文件的type,也是我们要讲的:

const type = response.headers['content-type']
const blob = new Blob([response.data], { type })

这里我们通过Response的header来获取type,然后再创建Blob对象,这样就可以正确的下载文件了。

其实content-type也可能是application/octet-stream,这个时候我们就需要通过file-type来获取文件的type了。

下面的代码是通过file-type来获取文件的type:

import {fileTypeFromStream} from 'file-type';
 
const type = await fileTypeFromStream(response.body);
const blob = new Blob([response.data], { type })

 

6. 总结

上面的方案这么多,其实最终还是落到a标签上,所以不管是通过浏览器的内置行为进行下载,还是通过ajax进行下载,文件下载的最终还是浏览器的行为。

我项目中遇到的需求如下:

首先window.open(URL)的这种方式和a标签方式一样对于pdf和图片都会打开文件,而并非直接下载,那么当然如果自动打开pdf或者图片,鼠标右击图片或者pdf右上角也会有下载入口。但是如果说需求是点击按钮直接下载文件,那么需要采取获取文件流然后拿到文件流通过a标签下载这种当时,当然获取文件流可以前端去做也可以后端做。

本次需求是通过oss的URL来下载文件。那么我选择前端去做获取文件二进制流。

const downFile = (fileUrl) => {
  console.log(fileUrl); // fileUrl是oss的url字符串


  // ********* 方式一 ************
  // window.open(fileUrl)  //window.open的方式


  // ********* 方式二 ************
  // let a = document.createElement("a")  //直接a标签的方式
  // a.download = 'aaa'
  // // a.href = window.URL.createObjectURL(blob)
  // a.href = fileUrl
  // a.click()
  // a.remove()



  // ********* 方式三 ************
  //直接下载文件并且前端获取文件二进制流
  const xhr = new XMLHttpRequest();
  xhr.open('GET', fileUrl, true);
  xhr.responseType = 'blob'; // 获取文件blob数据
  xhr.onload = function () {
    if (xhr.status !== 200) {
      ElMessage({
        type: 'error',
        message: `下载出现错误`,
      })
      return;
    }
    const newUrl = window.URL.createObjectURL(xhr.response); // 生成一个可用的临时url
    const a = document.createElement('a'); // 生成a标签调用点击事件
    a.setAttribute('href', newUrl);
    a.setAttribute('target', '_blank');
    a.setAttribute('download', fileName); // 自定义文件名
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };
  xhr.send();
}

感谢这位作者的分享,收获良多,特此记录。

https://juejin.cn/post/7254143696483991611 文章来源地址https://www.toymoban.com/news/detail-768012.html

到了这里,关于前端下载文件或者图片方式,window.open或者a标签形式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端几种下载文件的方式(url方式和文件流方式)

    前端实现下载功能是依赖于浏览器特性,而非JS特性 前端如何实现文件下载,防止浏览器自动打开可预览文件 https://blog.csdn.net/weixin_46074961/article/details/105677732 1.location.href 下载文件–window-location-href 对于浏览器不能打开的文件(例如:.rar .doc等)是可以实现文件下载的,但是对于浏

    2024年02月06日
    浏览(29)
  • 前端实现下载文件(包含压缩包下载)方式汇总

    默认最简单的下载方式是: window.open(后台接口API路径) ,但该方法弊端:因是新开窗口方式,前端展示上,每次会闪下。 此外,如果使用window.open(文件URL)方式: pdf、office文档、psd:直接下载。 图片、txt:新开窗口预览,不会下载;且txt预览,有时出现中文乱码问题。 一、

    2024年02月10日
    浏览(40)
  • 前端实现下载文件的各种方式

    前端涉及到的文件下载还是很多应用场景的,那么前端文件下载有多少种方式呢?每种方式有什么优缺点呢?下面就来一一介绍。 通过 a 标签的 download 属性来实现文件下载,这种方式是最简单的,也是我们比较常用的方式,先来看示例代码: 就上面的这个示例,我们点击下

    2024年02月16日
    浏览(36)
  • 前端下载文件(Blob)的几种方式使用Blob下载文件

    在前端下载文件是个很通用的需求,一般后端会提供下载的方式有两种: 1.直接返回文件的网络地址(一般用在静态文件上,比如图片以及各种音视频资源等) 2.返回文件流(一般用在动态文件上,比如根据前端选择,导出不同的统计结果 excel 等) 第一种方式比较简单,但

    2024年02月07日
    浏览(44)
  • 记录--盘点前端实现文件下载的几种方式

    前端涉及到的文件下载还是很多应用场景的,那么前端文件下载有多少种方式呢?每种方式有什么优缺点呢?下面就来一一介绍。 通过 a 标签的 download 属性来实现文件下载,这种方式是最简单的,也是我们比较常用的方式,先来看示例代码: 就上面的这个示例,我们点击下

    2024年02月13日
    浏览(41)
  • 前端常用的上传下载文件的几种方式,直接上传、下载文件,读取.xlsx文件数据,导出.xlsx数据

    1.1根据文件流Blob进行下载 1.2根据下载文件链接直接进行下载 html

    2024年02月12日
    浏览(29)
  • EasyExcel下载EXCEL文件,后台通过流形式输出到前端浏览器下载方式输出

    后端代码(参考): 依赖:

    2024年01月16日
    浏览(46)
  • vue 后端返回二进制流-前端通过blob对象下载文件-图片

    前言 在实际开发中我们经常会遇见下载文件的场景,比如下载合同,下载文件 下载文件有2种方式,一种是后端返回二进制流,前端通过blob对象接受根据不同类型下载 还有一种把地址直接在浏览器新窗口打开浏览器打开pdf可以预览和下载,其他文件直接下载 但不管是那种方

    2024年02月05日
    浏览(58)
  • JS打开新标签页(window.open应用)

    在 a标签 中通过设置target=”_blank”就可以实现打开新标签的效果。但有时候我们需要通过Javascript来打开新标签,那么怎么实现呢? 方法如下: window.open(“http://www.wlzhys.com“); 或者: window.open(“http://www.wlzhys.com“, “_blank”); //注意第二个参数 注意事项: 在IE中,如果要打开

    2024年02月16日
    浏览(39)
  • 【stable diffusion】图片批量自动打标签、标签批量修改(BLIP、wd14)用于训练SD或者LORA模型

    B站教学视频【:AI绘画】新手向!Lora训练!训练集准备、tag心得、批量编辑、正则化准备】 官方教程:https://github.com/darkstorm2150/sd-scripts/blob/main/docs/train_README-en.md#automatic-captioning 1.1 打标界面 根据需求,选择通用打标模型(BLIP)还是动漫打标模型(deepbooru) 设置好后,选择

    2024年02月12日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包