当前位置:   article > 正文

关于前端a标签下载,跨域下载重命名无效问题_a 标签下载重命名

a 标签下载重命名

问题描述:在项目中写了个文件流形式的公共下载函数,但是发现下载大文件时,出现了“假死”现象,点击下载之后半天没反应,于是又改成a标签点击链接下载,但是遇到跨域文件无法重命名问题。

js文件下载大体分为两种:

一、将文件以文件流形式下载到浏览器

将文件以文件流形式下载浏览器之后,再以此文件流为a标签中的href,模拟点击下载。

缺点:

  1. 这种方式下载小文件没有啥大问题,但是如果下载大文件,就会出现用户点击之后,浏览器半天没有反应,直到文件下载完成,浏览器才会显示文件下载完成(因为是将文件流下载完成之后,才模拟一个a标签,点击下载),用户则可能认为点击无效,则多次点击下载,导致下载很多个文件,给用户体验不好。
  2. 如果文件足够大,比方说十几G的文件下载,则可能会导致浏览器崩溃,因为文件流可能超出了内存。这个只是个人推测,没有实际测试。

网上已有大量该下载代码,这里贴一个网上的代码:

/**
 * 文件下载重命名,根据依赖file-saver改写
 */
/**
 * 获取 blob
 * @param  {String} url 目标文件地址
 * @return {cb}
 */
export function getBlob(url, cb) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.responseType = "blob";
  xhr.onload = function () {
    if (xhr.status === 200) {
      cb(xhr.response);
    }
  };
  xhr.send();
}

/**
 * 保存
 * @param  {Blob} blob
 * @param  {String} filename 想要保存的文件名称
 */
export function saveAs(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    navigator.msSaveBlob(blob, filename);
  } else {
    var link = document.createElement("a");
    var body = document.querySelector("body");

    link.href = window.URL.createObjectURL(blob);
    link.download = filename;

    // fix Firefox
    link.style.display = "none";
    body.appendChild(link);

    link.click();
    body.removeChild(link);

    window.URL.revokeObjectURL(link.href);
  }
}

/**
 * 下载
 * @param  {String} url 目标文件地址
 * @param  {String} filename 想要保存的文件名称
 */
export function renameDownload(url, filename) {
  getBlob(url, function (blob) {
	 saveAs(blob, filename);
  });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

二、直接模拟a标签点击下载

a标签点击链接下载。

缺点:

  1. 会出现跨域点击下载文件命名失效;
  2. txt,图片,pdf等文件格式浏览器直接打开,而不是下载问题。

解决方案:
但是这些问题可以通过添加header来解决,但具体是否所有浏览器都兼容,以及安全问题,本人没有深究。
下边贴代码:

/**
 * 下载
 * @param  {String} fileUrl 目标文件地址
 * @param  {String} filename 想要保存的文件名称
 */
export function renameDownload(fileUrl, fileName) {
  let link = document.createElement("a");
  //这里属性涉及到跨域问题后,设置无效
  //link.download = fileName;
  link.style.display = "none";
  //response-content-type=application/octet-stream,这里是为了防止图片,pdf,txt文件直接被浏览器打开
  //response-content-disposition的设置,解决跨域文件名重命名无效问题,encodeURIComponent防止文件名带特殊字符(例如&等)导致下载文件名出问题
  link.href =
    fileUrl +
    "?response-content-type=application/octet-stream&response-content-disposition=filename=" +
    ${encodeURIComponent(fileName)};
  document.body.appendChild(link);
  link.click();
  URL.revokeObjectURL(link.href);
  document.body.removeChild(link, fileName);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/63575
推荐阅读
相关标签
  

闽ICP备14008679号