文件下载XMRHttpRequert,fetch,axios

本文探讨了使用AJAX下载文件的挑战,介绍了如何通过Blob对象实现文件下载,并展示了处理文件类型和下载链接的示例。重点讲解了axios和FileReader在下载过程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

备注: ajax 没有流下载,没有合适的响应类型

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> -->
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.min.js"></script>
</head>
<body>
  <a href="文件下载链接" download="文件名">下载</a>
  <button id="download">点击下载</button>
  
</body>
</html>
const downloadEl = document.getElementById('download')

function downloadBlob(blob, filename) {
  const a = document.createElement('a')
  const href = window.URL.createObjectURL(blob)
  a.href = href
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  window.URL.revokeObjectURL(href)
}

// 必须支持FileReader
function fileToJson(blob) {
 return new Promise((resolve, reject) => {
    if (typeof FileReader === undefined) {
      return reject({ code: 0, blob })
    }

    const reader = new FileReader()
    reader.onloadend = (res) => {
      try {
        const jsonRes = JSON.parse(res.target.result)
        return resolve(jsonRes)
      } catch {
        return reject({ code: 0, blob })
      }
    }
    reader.onerror = (err) => {
      return reject(err)
    }
    reader.readAsText(blob)
  })
}

function isFile(blob) {
  return fileToJson(blob)
    .then(jsonRes => {
      console.log('error' + jsonRes)
      return Promise.reject()
    })
    .catch(res => {
      if (res && res.code === 0) {
        console.log('is file')
        return blob
      }
    })
}
  function requestFile({ url }, callback) {
      axios({
        responseType: 'blob',
        responseEncoding: 'utf8',
        method: 'get',
        url
      }).then(res => {
        callback(res)
      })
    }
function requestFile({ url }, callback) {
 	const xhr = new XMLHttpRequest();
 	xhr.open('get', url, true);
	xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	xhr.responseType = 'blob';
	xhr.responseEncoding = 'utf8';
	xhr.send();
	xhr.onload = function() {
	  // 获取headers
	  const responseHeaders = xhr.getAllResponseHeaders()
	  // console.log(responseHeaders, typeof responseHeaders) // 获取不到所有的headers
	  const arr = responseHeaders.trim().split(/[\r\n]+/);
	  const headers = {};
	  arr.forEach(function (line) {
	    const parts = line.split(': ');
	    const header = parts.shift();
	    const value = parts.join(': ');
	    headers[header] = value;
	  })
	
	  const data = xhr.response
	
	  callback({ data, headers })
	}
    xhr.onprogress = function() {}
    xhr.onerror = function() {}
    xhr.onabort = function() {}
    xhr.onloadend = function() {}
}

function requestFile({ url }, callback) {
 const request = new Request(url)
  request.headers = {
    "Content-type": "application/x-www-form-urlencoded"
  }
  fetch(request)
    .then(response => {
      const headers = {}
      for (const [key, value] of response.headers) {
        headers[key] = value
      }
      if (response.status === 200) {
        return response.blob().then(blob => {
          callback({ data: blob, headers })
        })
      }
    })
}
function download({ url, filename }) {
      // 获取文件,文件名称,文件大小等等
      requestFile({ url }, async ({ data, headers }) => {
        console.log(headers)

         // 保证后台filename 使用encodeURIComponent 方式编码 否则中文等会乱码
         // 保证后台 access-control-expose-headers: 'content-disposition'
         
        const content_disposition = headers['content-disposition']
        if (content_disposition) header_filename = decodeURIComponent(content_disposition.split('filename=')[1])
        if (!filename) filename = header_filename

        // 判断是否是文件
        await isFile(data)
        // 下载文件
        downloadBlob(data, filename)
      })
    }


    function downloadHandle() {
      download({
        filename: '2022中国显示学术会议会议通知.zip',
        url: 'https://s.laoyaoba.com/jwconference/dissertation2022/file/tz.zip'
      })
    }

    downloadEl.addEventListener('click', downloadHandle, false)

nodejs 简单文件下载
https://blog.youkuaiyun.com/Holly1945/article/details/123802482

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值