方法一:a标签的download

采用原生创建dom节点的方法,注册a标签,把文件的地址放入 a标签的href里面。再通过js触发事件。

  1. <div onClick={()=>{
  2. this.handleDownLoad(record)
  3. }}>
  4. 下载
  5. </div>
  6. handleDownLoad = async record =>{
  7. let aEle = document.getElementById('aElement');
  8. // 创建dom节点
  9. if(!aEle){
  10. try{
  11. aEle = document.creatElement('<a name="aElement">');
  12. }catch(e){
  13. aEle = document.createElement('a')
  14. }
  15. }
  16. // 把创建的dom节点挂载到dom树上
  17. document.body.appendChild(aEle);
  18. // 隐藏a标签
  19. aEle.style.display = 'none';
  20. aEle.href = 'https://xxxxx.com';
  21. aEle.download = '文件名称';
  22. aEle.click();
  23. }

方法二:form表单提交

为一个下载按钮添加click事件,点击时动态生成一个表单,利用表单提交的功能来实现文件的下载

  1. /**
  2. * 下载文件
  3. * @param {String} path - 请求的地址
  4. * @param {String} fileName - 文件名
  5. */
  6. function downloadFile (downloadUrl, fileName) {
  7. // 创建表单
  8. const formObj = document.createElement('form');
  9. formObj.action = downloadUrl;
  10. formObj.method = 'get';
  11. formObj.style.display = 'none';
  12. // 创建input,主要是起传参作用
  13. const formItem = document.createElement('input');
  14. formItem.value = fileName; // 传参的值
  15. formItem.name = 'fileName'; // 传参的字段名
  16. // 插入到网页中
  17. formObj.appendChild(formItem);
  18. document.body.appendChild(formObj);
  19. formObj.submit(); // 发送请求
  20. document.body.removeChild(formObj); // 发送完清除掉
  21. }

方法三:open或location.href

本质上和a标签访问下载链接一样

  1. window.open('downloadFile.zip');
  2. location.href = 'downloadFile.zip';

方法四:Blob对象

调用api,将文件流转为Blob二进制对象, :::danger 注:IE10以下不支持。 ::: 思路: 发请求获取二进制数据,转化为Blob对象,利用URL.createObjectUrl生成url地址,赋值在a标签的href属性上,结合download进行下载。

  1. /**
  2. * 下载文件
  3. * @param {String} path - 下载地址/下载请求地址。
  4. * @param {String} name - 下载文件的名字/重命名(考虑到兼容性问题,最好加上后缀名)
  5. */
  6. downloadFile (path, name) {
  7. const xhr = new XMLHttpRequest();
  8. xhr.open('get', path);
  9. xhr.responseType = 'blob';
  10. xhr.send();
  11. xhr.onload = function () {
  12. if (this.status === 200 || this.status === 304) {
  13. // 如果是IE10及以上,不支持download属性,采用msSaveOrOpenBlob方法,但是IE10以下也不支持msSaveOrOpenBlob
  14. if ('msSaveOrOpenBlob' in navigator) {
  15. navigator.msSaveOrOpenBlob(this.response, name);
  16. return;
  17. }
  18. /*
  19. 如果发送请求时不设置xhr.responseType = 'blob',
  20. 默认ajax请求会返回DOMString类型的数据,即字符串。
  21. 此时需要使用两处注释的代码,对返回的文本转化为Blob对象,然后创建blob url,
  22. 此时需要注释掉原本的const url = URL.createObjectURL(target.response)。
  23. */
  24. /*
  25. const blob = new Blob([this.response], { type: xhr.getResponseHeader('Content-Type') });
  26. const url = URL.createObjectURL(blob);
  27. */
  28. const url = URL.createObjectURL(this.response); // 使用上面则注释此行
  29. const a = document.createElement('a');
  30. a.style.display = 'none';
  31. a.href = url;
  32. a.download = name;
  33. document.body.appendChild(a);
  34. a.click();
  35. document.body.removeChild(a);
  36. URL.revokeObjectURL(url);
  37. }
  38. };
  39. }
  1. // 上面方法本地测试有时会有跨域问题,下面使用axios重写一下
  2. // 已经配置好proxy
  3. downloadFile (path, name) {
  4. axios.get({
  5. url: path,
  6. method: 'get'
  7. }).then(res => {
  8. const blob = new Blob([res.data], { type: res.headers['content-type'] });
  9. const url = URL.createObjectURL(blob);
  10. const a = document.createElement('a');
  11. a.style.display = 'none';
  12. a.href = url;
  13. a.download = name;
  14. document.body.appendChild(a);
  15. a.click();
  16. document.body.removeChild(a);
  17. URL.revokeObjectURL(url);
  18. })
  19. }

该方法不能缺少a标签的download属性的设置。
因为发请求时已设置返回数据类型为Blob类型(xhr.responseType = ‘blob’),所以target.response就是一个Blob对象,打印出来会看到两个属性size和type。虽然type属性已指定了文件的类型,但是为了稳妥起见,还是在download属性值里指定后缀名,如Firefox不指定下载下来的文件就会不识别类型。

方法五:利用Base64

  1. /**
  2. * 下载文件
  3. * @param {String} path - 下载地址/下载请求地址。
  4. * @param {String} name - 下载文件的名字(考虑到兼容性问题,最好加上后缀名)
  5. */
  6. downloadFile (path, name) {
  7. const xhr = new XMLHttpRequest();
  8. xhr.open('get', path);
  9. xhr.responseType = 'blob';
  10. xhr.send();
  11. xhr.onload = function () {
  12. if (this.status === 200 || this.status === 304) {
  13. const fileReader = new FileReader();
  14. fileReader.readAsDataURL(this.response);
  15. fileReader.onload = function () {
  16. const a = document.createElement('a');
  17. a.style.display = 'none';
  18. a.href = this.result;
  19. a.download = name;
  20. document.body.appendChild(a);
  21. a.click();
  22. document.body.removeChild(a);
  23. };
  24. }
  25. };
  26. }