返回

浏览器下载文件检测难题:下载管理器 API 帮你解决

javascript

浏览器下载文件检测:解决下载状态难题

问题:下载过程中难以把握

在浏览器中,当用户单击文件下载链接时,浏览器会自动发起下载过程。然而,对于开发人员而言,如何可靠地检测下载的启动和完成一直是一个难题。

传统方法的局限性

传统上,开发人员使用以下方法来检测文件下载:

  • 多部分响应: 此方法涉及在响应中发送一个空HTML文件和一个可下载文件。虽然在某些浏览器中有效,但它在Internet Explorer和Safari中会失败。
  • 轮询服务器: 此方法需要调用服务器以启动文件创建,然后轮询服务器直到文件准备好。这需要在服务器上创建临时文件,可能会造成效率低下。

解决之道:下载管理器 API

现代浏览器提供了下载管理器 API ,它允许开发人员监听并查询下载状态。使用此API,我们可以可靠地检测文件下载的启动和完成。

步骤指南

要使用下载管理器 API,请遵循以下步骤:

  1. 创建下载链接,使用download属性指定文件名称:
    <a href="file-url" download="file-name">下载文件</a>
    
  2. 为下载链接添加点击事件侦听器:
    document.querySelector('a').addEventListener('click', (e) => {
      e.preventDefault();
    });
    
  3. 在点击事件处理程序中,获取下载管理器 API:
    const dm = navigator.downloadManager;
    
  4. 使用 getAll() 方法获取当前下载状态:
    dm.getAll().then((dls) => {
      console.log(dls); // Array of downloads
    });
    
  5. 检查下载状态(IN_PROGRESSSUCCESSFAILED):
    if (dls.length > 0) {
      const status = dls[0].state;
      // 根据状态更新用户界面,例如显示或隐藏等待指示器
    }
    

代码示例

<!DOCTYPE html>
<html>
<head>
  
</head>
<body>
  <a href="file-url" download="file-name" id="download-link">下载文件</a>

  <script>
    document.querySelector('#download-link').addEventListener('click', (e) => {
      e.preventDefault();
      const dm = navigator.downloadManager;
      dm.getAll().then((dls) => {
        if (dls.length > 0) {
          const status = dls[0].state;
          if (status === 'IN_PROGRESS') {
            // 显示等待指示器
          } else if (status === 'SUCCESS') {
            // 隐藏等待指示器
          } else if (status === 'FAILED') {
            // 处理错误
          }
        }
      });
    });
  </script>
</body>
</html>

常见问题解答

Q1:此方法是否适用于所有浏览器?
A1:下载管理器 API 在大多数现代浏览器中得到支持,包括 Chrome、Firefox、Safari 和 Edge。

Q2:是否需要在服务器端执行任何操作?
A2:不需要,此方法是客户端实现的。

Q3:我可以使用此方法来跟踪多个并发下载吗?
A3:是的,下载管理器 API 提供了一个下载数组,允许你同时跟踪多个下载。

Q4:我该如何处理下载失败的情况?
A4:下载管理器 API 提供了 error 事件,你可以监听该事件以处理下载失败。

Q5:除了显示等待指示器之外,此方法还有什么其他用途?
A5:此方法还可以用于其他目的,例如更新进度条、提供下载详细信息,甚至在下载完成后自动打开文件。