简介

我们知道,下载文件是一个非常常见的需求,但由于浏览器的安全策略的限制,我们通常只能通过一个额外的页面,访问某个文件的 url 来实现下载功能,但是这种用户体验非常不好。

幸好,HTML 5 里面为 <a> 标签添加了一个 download 的属性,我们可以轻易的利用它来实现下载功能,再也不需要用以前的笨办法了。

原理

我们先看看 download 的使用方法:

 <a href="http://somehost/somefile.zip" download="filename.zip">Download file</a>

看看上面的代码,只要为 <a> 标签添加 download 属性,我们点击这个链接的时候就会自动下载文件了~

顺便说下,download 的属性值是可选的,它用来指定下载文件的文件名。像上面的例子中,我们下载到本地的文件名就会是 filename.zip 拉,如果不指定的话,它就会是 somefile.zip 这个名字拉!

事实上,用 JavaScript 来下载文件也是利用这一特性来实现的,我们的 JavaScript 代码不外乎就是:

  • 用 JavaScript 创建一个隐藏的 <a> 标签

  • 设置它的 href 属性

  • 设置它的 download 属性

  • 用 JavaScript 来触发这个它的 click 事件

翻译成 JavaScript 代码就是:

var a = document.createElement('a');
var url = window.URL.createObjectURL(blob);
var filename = 'what-you-want.txt';
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);

好拉,是不是看到有个陌生的东东呢?

window.URL

window.URL 里面有两个方法:

  • createObjectURL 用 blob 对象来创建一个 object URL(它是一个 DOMString),我们可以用这个 object URL 来表示某个 blob 对象,这个 object URL 可以用在 href 和 src 之类的属性上。

  • revokeObjectURL 释放由 createObjectURL 创建的 object URL,当该 object URL 不需要的时候,我们要主动调用这个方法来获取最佳性能和内存使用。

知道了这两个方法之后,我们再回去看看上面的例子就很容易理解了吧!只是用 blob 对象来创建一条 URL,然后让 <a> 标签引用该 URL,然后触发个点击事件,就可以下载文件了!

那么问题来了,blob 对象哪里来?

Blob 对象

Blob 全称是 Binary large object,它表示一个类文件对象,可以用它来表示一个文件。根据 MDN 上面的说法,File API 也是基于 blob 来实现的。

由于本文的主题是讲 JavaScript 下载文件,那我们构建 blob 的方式就是通过服务器返回的文件来创建 blob 拉!

而最简单的方式就是用 fetch API 了,我们可以整合上面的例子:

fetch('http://somehost/somefile.zip').then(res => res.blob().then(blob => {var a = document.createElement('a');var url = window.URL.createObjectURL(blob);var filename = 'myfile.zip';a.href = url;a.download = filename;a.click();window.URL.revokeObjectURL(url);
}))

很简单对吧!

你可能会问,何必这么麻烦呢?直接写成下面这样不就好了:

<a href="http://somehost/somefile.zip" download="myfile.zip">Download file</a>

嗯,对于这种写法,我只能说,你做的太正确了!如果你要下载的是已经存在服务器上面的静态文件的话,那么写成这样是最方便的。

为什么要用 JavaScript 下载文件

好拉,说了半天,其实我们一直说的都是:「不要用 JavaScript 下载文件拉,限制多多,又不好用,直接用 html 就好拉,简单方便又快捷」这个论调。

事实上也确实如此,但有些时候我们确实需要通过 JavaScript 来做一些预处理。

权限校验

有些时候,我们需要对下载做一些限制,最常见的就是权限校验了,如检查该用户是否有下载的权限,是否有高速下载的权限等等。这时候,我们可以利用 JavaScript 做一些预处理。如:

fetch('http://somehost/check-permission', options).then(res => {if (res.code === 0) {var a = document.createElement('a');var url = res.data.url;var filename = 'myfile.zip';a.href = url;a.download = filename;a.click();} else {alert('You have no permission to download the file!');}
});

在这个例子里面,我们没有用 blob 来构建 URL,而是通过后端服务器来计算出用户的下载链接,然后再利用之前提到的动态创建 <a> 标签的方式来实现下载,很简单吧!

转自:[前端早读课]http://mp.weixin.qq.com/s/U_LuC2Nyv4ZcNpX0tHDP3g

转载于:https://www.cnblogs.com/longm/p/6565805.html

如何用 JavaScript 下载文件相关推荐

  1. javascript下载文件几种方式,接收后台返回流下载或直接下载文件

    目录 1 javascript下载文件7中方式 1.1 window.location.href下载 1.2 window.location下载 1.3 iframe下载 1.4 form表单的形式下 ...

  2. js下载文件,javascript下载文件,FileSaver.js,页面元素保存成文件

    js下载文件,javascript下载文件,FileSaver.js,页面元素保存成文件 ================================ ©Copyright 蕃薯耀 2020-07 ...

  3. JavaScript 下载文件、图片

    前提是我们拿到的数据必须是Blob格式的数据 一.下载文件 let downLoadFile = (obj, name, suffix) => {const url = window.URL.c ...

  4. 如何用php下载文件?

    直接上代码: function download_file($url = '', $fileName = '') {$ch = curl_init();$fp = fopen($fileName, ' ...

  5. JavaScript 下载大文件解决方案(Blob+OjbectURL)

    JavaScript 下载大文件解决方案(Blob+OjbectURL) 参考文章: (1)JavaScript 下载大文件解决方案(Blob+OjbectURL) (2)https://www.cn ...

  6. python单击url下载网页文件_使用不带url的python脚本从网页下载文件,调用onClick函数 - javascript...

    有一个网页带有链接"单击下载",单击该链接可以下载文件. 我可以通过转到网页并单击此链接来手动下载此文件,但是我需要通过python脚本下载此文件. 如果我看到源代码,则可以看到锚 ...

  7. 使用Javascript / jQuery下载文件

    本文翻译自:Download File Using Javascript/jQuery I have a very similar requirement specified here . 我在这里指 ...

  8. 如何用Jmeter上传下载文件

    文章目录 如何用Jmeter上传下载文件 1.上传文件 1.1 准备: 1.2 步骤: 1.3 拓展点:MIME类型(关于MIME填什么) 1.4 高级用法:批量上传文件 2.下载文件 2.1 准备: ...

  9. JavaScript实战篇 -ajax方式实现js打包下载文件

    一.问题描述 在我们日常开发中,会遇到批量下载方面的问题;如上图所示,我们要批量下载图片,接下来我们就模拟实现这个功能,并将下载文件打包下载; 二.准备工作 2.1 JSZip JSZip 是一个 j ...

最新文章

  1. 【C语言】三种不同方法实现简易整型计算器 (三个方法递增优化)
  2. Google App Engine技术架构之Google App Engine架构
  3. CentOS查看进程的线程数方法
  4. Serverless 解惑——函数计算如何访问 SQL Server 数据库
  5. maven 之 setting.xm 的配置详解、说明
  6. 未能加载nStuff.ScriptSharp.Web.dll
  7. javascript实例:路由的跳转
  8. 【sklearn第二十六讲】模型评价
  9. 科赫雪花c语言程序设计,用 C 语言画科赫雪花
  10. 小米10开始抓取日志怎么关闭_日志MIUI 10 9.5.22 内测更新资讯
  11. vrrp和mstp实现网关冗余备份以及链路的负载均衡
  12. java date 减去5分钟_java里让一个date每次加5分钟等于另外一个指定的date
  13. 【SCOI 2005】王室联邦 树上分块?
  14. SteamVR Unity工具包(VRTK)之概览和控制器事件
  15. 数据结构实验报告—栈和队列
  16. midi java_Java程序中添加播放MIDI音乐功能的实现方法详解
  17. 自定义SpringBoot程序启动图标
  18. 校园表白墙网站PHP源码
  19. linux 编辑文件 cat 跳到指定行,Linux基础命令(二)
  20. java 重写paint_java – JLabel:重写paintComponent()之后.如何...

热门文章

  1. 如何成为一名优秀的web前端工程师
  2. Web开发必学的8个网页优化技巧!
  3. apache禁用不安全的http法_tomcat禁用不安全的HTTP方法
  4. python删除列表内容_python删除列表内容
  5. 计算机三级标题,计算机三级考试题目
  6. html外联内联,HTML内联元素
  7. Java编写优雅接口,看看别人后端API接口写得,那叫一个优雅!
  8. mysql 表2符合表1,MySQL:表tbl_2_1_15已满
  9. android 模拟crash_Android 收集Crash信息及用户操作步骤
  10. python新手入门到放弃_python萌新:从零基础入门到放弃