uniapp的移动端h5实现文件下载兼容手机各版本浏览器

需求:uniapp做的h5项目,后端返回文件列表,手机浏览器访问h5服务进入文件列表点击下载对应文件并打开。

uniapp的移动端h5实现文件下载兼容手机各版本浏览器_第1张图片

解决方法一:

一般最常见的兼容性解决方案步骤是:①拼接文件下载链接地址②动态生成a标签,设置默认属性,把下载地址给到a标签href属性③触发一个click事件点击a标签实现文件下载④下载完成移除a标签,释放内存

具体实现步骤如下:

export const downloadByFileid = (res) => {
  const filePath = `/api/file/downloadByType/${res.fileId}`;
  const tempLink = document.createElement("a");
  tempLink.style.display = "none";
  tempLink.href = filePath;
  tempLink.setAttribute("download", res.fileName);
  tempLink.setAttribute("target", "_blank");
  document.body.appendChild(tempLink);
  tempLink.click();
  document.body.removeChild(tempLink);
};

问题:使用以上方法能够基本兼容手机端大多数浏览器,此时也暴露了一个安全性问题, 如果涉及到合同、协议等其他涉密文件,下载地址没有token鉴权,别人通过地址也能够直接下载浏览,此时想到了第二个解决方法。

解决方法二:

还是通过创建a标签的方式下载,只不过走前端统一封装接口请求,后端接口返回Blob文件流格式,这样就能够做到先请求接口拿到文件流,再去走创建a标签下载那一套步骤,从而实现了token鉴权解决安全性的问题。

export const downloadByBlob = async (res) => {
  try {
    const fileData = await getDownloadFileByTypeApi({
      fileId: res.fileId,
    });
    const filename = `${res.fileName}`;
    const blob = new Blob([fileData], { type: `${fileData.fileType}` });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.style.display = "none";
    a.href = url;
    a.download = filename;
    const body = document.getElementsByTagName("body")[0];
    body.appendChild(a);
    a.click();
    body.removeChild(a);
    window.URL.revokeObjectURL(url);
  } catch (error) {
    this.$u.toast(error);
  }
};

问题:使用上述方法在pc端切换各主流浏览器调试后无误以为没问题了,结果手机浏览器一测就寄了,安卓手机自带浏览器,qq浏览器等一些浏览器下载不了页面白屏要么就是格式会错乱,chrome和edge又是可以下载的,查证后发现有些浏览器不能识别Blob格式的文件,最终商讨解决还是得回到第一种使用绝对地址方式下载,后端配合通过其他方式实现接口鉴权。(如果是pc端应用的话推荐使用这种方式)

最终解决:

想到两种比较容易实现的思路:

①在自己的服务器把文件生成绝对地址,给链接地址设置时效性,超时则清空服务器资源,使得下载链接无效,也可以很好的节约文件服务器资源。

②给下载链接地址做权限校验,上面第二种解决方式是通过走封装请求token会放到请求头携带过去,现在则是通过参数拼接的方式把token携带过去后端验证,需要后端做兼容处理。

export const downloadByFileid = (res) => {
  const filePath = `/api/file/downloadByType/${res.fileId}/?token=${token}`;
  // 以下步骤省略......
};

最后使用第二种方式,后端接口改造后测试大多数手机端浏览器发现都可以正常下载了,虽然说可能不是最优解决但是能够兼容大多数浏览器了,目前没遇到别的问题,遇到问题记录一下,后续有更好的实现方式会加上。

你可能感兴趣的:(前端,uni-app,vue.js,html5)