likes
comments
collection

怎么使用 JavaScript 下载文件

作者站长头像
站长
· 阅读数 13

下载文件是上网的重要一个方面。每天都有很多的文件被下载,下载的内容有二进制文件(比如应用,图片,视频或者音频),也有纯文本文件。

Web 开发者可以下面的介绍将下载的特性添加到应用中。

我们将介绍三种不同的方法:

  • 基本模式 -- 仅使用 HTMl 元素
  • 使用 Javascript,其带有 Fetch APIHTML 元素
  • 使用 XMLHttpRequestHTML 元素,但是在复杂的场景,我们应该加个进度条

方法 1:仅使用 HTMl 元素

第一个,也是最简单的一个方法:我们创建一个 HTML 锚点元素 <a>,并设置其 download 属性。 、 根据定义,当用户点击该超链接时,download 属性指明目标元素(文件应该指定在 href 属性中)将被下载。

同时,通过 download 属性,我们可以指定下载后文件的新名称。因此,如果我们想指定下载文件的名字,我们应该使用该属性。然而,当 window 中的本地窗口弹出的时候,用户仍然可以更改文件的名字,当然,默认的文件名是我们设定的 download 值。

如果省略 download 值,则使用原始文件的名字。

怎么使用 JavaScript 下载文件

这个方法很棒,我们不需要基于该下载过程执行任何操作。

与此同时,即使我们不能在页面渲染锚点 HTMl 元素,我们还可以通过 JavaScript 来使用该方法。

怎么使用 JavaScript 下载文件

上面的方法,做的事情一样,我们只是动态创建了锚点 HTML 元素,在下载动作执行后,我们移除该元素。

  • IMG_URL 我们想下载的图片的 URL
  • FILE_NAME 被下载下来的文件的新名字

这个方法的局限在于它必须同源策略,因此该属性在同源的 URIs 中正常工作。

一个常见的场景是,当我们想从另外一个服务中下载图片,但是浏览器被没有下载它,而是打开了一个新的 tab 页面预览。

download 此方法的关键是下载的过程自动启动,并且可以在浏览器本地查看。

怎么使用 JavaScript 下载文件

请注意上面的下载过程是如何发送到浏览器进行管理的,浏览器提供了控屏并显示下载进度。

方法 2:Fetch API 和 HTML 元素

第二个和第三个方法采用的技术相同,都是使用了锚点元素,但是我们将文件内容转换成 Blob 而不是使用图片的 URL。然后我们使用 createObjectURL 方法将它创建成 DOMString

怎么使用 JavaScript 下载文件

请注意,我们最后使用了 URL.revokeObjectURL,这在内存管理方面很重要。当我们使用 URL.createObjectURL,一个新的 URL 对象就被创建了,及时它是用相同的 blob 对象调用的。

只要 URL 对象被创建了,它会在页面的生命周期中存活。当页面重新加载,浏览器才释放所有的 URL 对象。然而,当不再需要这些 URL 对象时,我们需要手动释放,这对提升性能和减少内存使用很重要。

该方法关键点是下载过程将自动启动,但是在我们的应用程序中,只有在下载完成后才会传递给浏览器。

怎么使用 JavaScript 下载文件

注意上面的 GIF 图。当我们点击下载按钮,看起来没什么事情发生,这是因为我们的程序中的下载乘务在异步进行中,当它下载完成后再传递给浏览器。

出现该浏览器窗口并点击保存后,该文件将自动保存在我们的计算机上。

使用这种方法,我们可以下载任何服务中的任何类型文件。然而,问题是,这个方法在程序内部下载,用户点击之后,会认为什么也没有发生。因此,在下载大文件的时候,我们应该给一个下载进度条提示。

与此同时,当文件完成下载后,当我们需要在应用程序中执行某些操作,该方法很有用处。比如,展示一个信息,发送一个请求给后端来渲染一个新页面等等...

方法 3:XMLHttpRequest 和 HTML 元素

方法三和方法二很相似,我们依旧使用 BlobcreateObjectURL,但是我们将使用 XMLHttpRequest 而不是 Fetch API

我们使用 XMLHttpRequest 来代替 Fetch 是因为目前 Fetch API 不提供进度接口,而 XMLHttpRequest 提供。

怎么使用 JavaScript 下载文件

一开始,onreadystatechange 方法和方法二有点类似。将响应的数据作为一个 Blob 对象下载,创建一个 DOMString,然后使用锚点元素下载该文件。

onprogress 方法中,我们使用了 e.loadede.total 来计算下载进度的百分比和经过的时间,还有下载的速度和剩余的时间。

请注意上面的 GIF 图,我们的行为和方法二的一样,但是我们可以监控进度。文件完全被下载之后,它将被发送到浏览器,最终保存在磁盘中。

总结

上面的三种方法,后者是对前者的升级。

第一个方法很简当。我们可以通过浏览器本身控制下载的进度。当应用程序不必要根据下载状态执行某些操作的时候,该方法是首选。

第二个方法,当文件被下载完成之后,才通知浏览器。这种方法是,我们可以控制应用程序内部的下载,根据其状态做出反应。这种方法对下载小文件比较友好快速。当下载文件太大时,如果 UI 上没有提示下载,用户可能会认为应用程序有问题。

在最后一个方法中,我们实现了下载的进度,这与浏览器显示进度类似。

本文为译文,采用意译的形式。原文地址:itnext.io/how-to-down…

往期精彩推荐

如果读者觉得文章还可以,不防一键三连:关注➕点赞➕收藏