JavaScript文件下载多种实现方法总结

 更新时间:2026年01月26日 09:55:14   作者:天外天-亮  
在Web开发中,实现用户在不离开当前页面的情况下下载文件是一个常见的需求,这篇文章主要介绍了JavaScript文件下载多种实现方法总结的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、<a> 标签的 download 属性 (最简单)

这是实现文件下载最简单直接的方式,尤其适用于下载静态资源或已知URL的文件。

HTML5为 <a> 标签引入了 download 属性。当用户点击带有 download 属性的链接时,浏览器会强制下载链接指向的资源,而不是导航到它。你还可以为 download 属性指定一个值,作为建议的下载文件名。

<!--下载同源文件,并建议文件名为report.pdf 
<a href="/files/report.pdf" rel="external nofollow"  download="report.pdf'>下载报告</a>

<!-- 下载图片,浏览器会自动推断文件名和类型
<a href="/images/logo.png" rel="external nofollow"  download>下载Logo</a>

<!-- 下载跨域文件(需要服务器设置 Access-Control-Allow-0rigin)
<a href="https://example,com/somefile.zip" rel="external nofollow"  download="archive.zip">下载跨域文件</a>

优点:

1、实现简单,无需JavaScript。

2、语义化好。

3、兼容性好 (现代浏览器都支持)。

缺点:

1、同源限制: 对于跨域资源,如果服务器没有设置正确的 Access-Control-Allow-Origin 头部,download 属性可能会被忽略(浏览器可能仍会尝试导航而不是下载,或者下载的文件名不是你指定的)。

2、动态内容: 不适用于需要动态生成或通过API获取数据后再下载的场景。

3、请求控制: 无法添加自定义请求头(如Authorization)。

二、window.open() 或 window.location.href

这种方式本质上是导航到一个URL,如果服务器在该URL响应时设置了 Content-Disposition: attachment; filename=“filename.ext” 这样的HTTP头部,浏览器就会触发下载。

// 直接导航,依赖服务器响应头
function downloadFileFromServer(url) {
  window.location.href=url;
}
// 在新标签页尝试打开,也依赖服务器响应头
function downloadFileInNewTab(url) {
  window.open(url,' blank');
}
// 使用示例
downloadFileFromServer('/api/download/data.csv');
downloadFileInNewTab('https://example.com/api/get-file?id=123');

优点:

1、实现简单。

2、可以下载跨域文件,只要服务器正确设置了响应头。

缺点:

1、文件名控制在后端: 文件名由服务器的 Content-Disposition 头部决定,前端无法直接控制(除非文件名在URL参数中)。

2、用户体验: window.location.href 会导致当前页面跳转,如果下载失败或响应不是文件流,用户体验可能不好。window.open() 可能被弹出窗口拦截器阻止。

3、请求控制: 同样无法添加自定义请求头。

4、不适用于Blob数据: 不适用于前端生成的Blob数据下载。

三、使用 Fetch API 或 XMLHttpRequest (XHR) + Blob + URL.createObjectURL()

这是目前最灵活和强大的前端下载方式,尤其适用于需要认证、动态生成内容或处理从API获取的二进制数据。

原理:

1、使用 Fetch API 或 XHR 向服务器发送请求,获取文件数据。将响应体(通常是二进制数据)转换为 Blob 对象。

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

3、使用 URL.createObjectURL(blob) 为这个 Blob 对象创建一个临时的URL。这个URL指向浏览器内存中的数据。

4、创建一个隐藏的 <a> 标签,将其 href 属性设置为这个临时URL,并设置 download 属性为期望的文件名。

5、通过JavaScript模拟点击这个 <a> 标签,触发下载。

6、(可选但推荐)下载完成后,使用 URL.revokeObjectURL(objectURL) 释放之前创建的临时URL,以避免内存泄漏。

async function downloadWithFetch(apiUrl,filename = 'downloaded-file') {
  try {
    const response =await fetch(apiUrl,{
      method:'GET',//或'POST',可以带请求体
      headers:
        'Authorization':'Bearer YOUR ACCESS TOKEN',// 示例:添加认证头
        // 'Content-Type':'application/json' // 如果是POST请求且有请求体。
        // body:JSON.stringify({params:'some_param'}) // 示例:POST请求体
    });
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const blob=await response.blob(); // 获取响应体为Blob对象
    const url = URL.create0bjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    // 需要将a标签添加到D0M中才能触发点击(在某些浏览器中
    document,body.appendchild(a);
    a.click();
  
    // 清理
    document.body.removechild(a);
    URL.revoke0biectURL(url);  // 释放URL对象
    console.log('文件下载成功');
  } catch (error) {
    console.error('下载失败:',error);
  }
}

优点:

1、完全控制: 可以设置自定义请求头(如认证信息)、请求方法、请求体。

2、处理动态数据: 非常适合从API获取数据后下载。

3、错误处理: 可以精确捕获和处理请求过程中的错误。

4、进度指示: XMLHttpRequest 支持 progress 事件,可以实现下载进度条(Fetch API 也可以通过 ReadableStream 实现,但相对复杂些)。

5、前端生成文件: 可以将前端生成的Canvas图像、JSON数据等转换为Blob直接下载。

缺点:

1、实现相对复杂。

2、需要处理 Blob 和 Object URL。

3、注意内存管理,及时 revokeObjectURL。

选择哪种下载方式取决于具体的需求:

1、最简单场景(静态文件): 优先考虑 <a> 标签的 download 属性。

2、需要服务器处理并返回文件流(可跨域): window.open() 或 window.location.href,并确保服务器设置 Content-Disposition。

3、需要自定义请求(如认证)、处理API返回的二进制数据、或希望对下载过程有更多控制: 使用 Fetch API 或 XHR 结合 Blob 和 URL.createObjectURL()。

总结

到此这篇关于JavaScript文件下载多种实现方法的文章就介绍到这了,更多相关JS文件下载方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript中的window.location.search方法简介

    javascript中的window.location.search方法简介

    window.location.search方法是截取当前url中“?”后面的字符串,示例如下,感兴趣的朋友可以参考下
    2013-09-09
  • mock.js实现模拟生成假数据功能示例

    mock.js实现模拟生成假数据功能示例

    这篇文章主要介绍了mock.js实现模拟生成假数据功能,结合实例形式分析了mock.js插件生成模拟数据的相关操作技巧,需要的朋友可以参考下
    2019-01-01
  • 从理论角度讨论JavaScript闭包

    从理论角度讨论JavaScript闭包

    本文将介绍一个在JavaScript经常会拿来讨论的话题 —— 闭包(closure)。 闭包其实已经是个老生常谈的话题了; 有大量文章都介绍过闭包的内容, 尽管如此,这里还是要试着从理论角度来讨论下闭包, 看看ECMAScript中的闭包内部究竟是如何工作的
    2019-04-04
  • 腾讯的ip接口 方便获取当前用户的ip地理位置

    腾讯的ip接口 方便获取当前用户的ip地理位置

    在论坛中闲逛,无意中发现腾讯的ip接口。还是挺有意思的。大家可以利用下,这个IP接口所查询到的还是比较准确,我发给几个朋友测试了一下都是正确的,毕竟是腾讯的东西。
    2010-11-11
  • 使用Bootstrap美化按钮实例代码(demo)

    使用Bootstrap美化按钮实例代码(demo)

    这篇文章主要介绍了使用Bootstrap美化按钮实例代码(demo),非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • JavaScript实现复制图片功能的方法示例

    JavaScript实现复制图片功能的方法示例

    本文主要介绍了在JavaScript中实现复制图片的方法,先介绍了实现复制的前置知识,包括传统的 execCommand 方法及其优缺点和 Clipboard API,然后详细阐述了如何将不同形式的图片转化为blob对象并通过Clipboard API实现复制,还提及了兼容性问题及预览、下载图片的实现思路
    2025-03-03
  • 理解Javascript_14_函数形式参数与arguments

    理解Javascript_14_函数形式参数与arguments

    在'执行模型详解'的'函数执行环境'一节中对arguments有了些许的了解,那么让我们深入的分析一下函数的形式参数与arguments的关系。
    2010-10-10
  • 详细聊聊TypeScript中unknown与any的区别

    详细聊聊TypeScript中unknown与any的区别

    unknown类型比较谦虚,就和他本身的意思一样,他从不祸害到其他的变量,但是any类型就是那种恶霸,属于什么都不管,谁也不敢管的类型,这篇文章主要给大家介绍了关于TypeScript中unknown与any区别的相关资料,需要的朋友可以参考下
    2021-10-10
  • 一文探索执行JavaScript函数的多种方法

    一文探索执行JavaScript函数的多种方法

    在前端开发中,动态执行 JavaScript 函数是一种强大的能力,能够帮助开发者实现灵活的逻辑控制,本文将和大家探讨一下几种常用的执行方法,需要的可以了解下
    2025-01-01
  • JavaScript判断是否是微信浏览器

    JavaScript判断是否是微信浏览器

    通过判断UA中是否有关键字micromessenger,有的话则是微信内置浏览器。下面小编给大家分享实现代码,代码简单易懂,需要的朋友可以参考下
    2016-06-06

最新评论