使用Ajax直接获取文件下载进度是有挑战的,因为标准的Ajax请求并不直接支持进度更新,尤其是对于文件下载。不过,有几种方法可以间接实现这一功能:

使用Blob和ProgressEvent

对于现代浏览器,可以利用XMLHttpRequestresponseType设置为blob,结合onprogress事件来监听下载进度。这种方法不严格属于Ajax,但它利用了Ajax的核心——XMLHttpRequest对象。

        
HTML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> </style> </head> <body> <button class="btn">下载</button> <div class="progress"> 当前下载:<span class="current"></span> 总大小:<span class="total"></span> </div> <script> const btn = document.getElementsByClassName('btn')[0] const progress = document.getElementsByClassName('progress')[0] const current = document.getElementsByClassName('current')[0] const total = document.getElementsByClassName('total')[0] const downloadFile = (url) => { const xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'blob'; xhr.onload = function (e) { if (this.status === 200) { const url = window.URL.createObjectURL(this.response) const a = document.createElement('a'); a.href = url; a.download = url.split('/').pop() a.click() window.URL.revokeObjectURL(url) a.remove() } } xhr.onprogress = (e) => { if (e.lengthComputable) { const percent = e.loaded / e.total current.innerHTML = (e.loaded / 1024 / 1024).toFixed(2) + 'M' total.innerHTML = (e.total / 1024 / 1024).toFixed(2) + 'M' } else { // 无法计算进度 } } xhr.send() } btn.onclick = function () { downloadFile('./video.mp4') } </script> </body> </html>
下载进度
下载进度
  1. 初始化请求:创建一个新的XMLHttpRequest对象,并用open()方法初始化一个GET请求,指向要下载的文件URL。确保请求为异步模式。

  2. 设置响应类型:为了处理文件下载,需将responseType属性设置为blob。这样,响应将以二进制大对象(Blob)的形式返回,适用于文件处理。

  3. 监听进度事件:通过添加onprogress事件监听器,可以实时获取下载进度信息。事件对象的loaded属性表示当前已下载的字节数,而total属性(如果可用)表示文件总字节数。利用这两个值,可以计算出下载完成的百分比。

  4. 处理加载完成:同时,添加onload事件监听器来捕获文件下载完成的时刻。此时,可通过xhr.response访问到Blob形式的文件内容,之后可根据需求处理这个Blob,比如触发文件下载或在页面中展示。

  5. 发送请求:使用send()方法发送HTTP请求。