download.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { objTypeOf, blobToText } from "./utils";
  2. function parseDownloadFilename(dispositionInfo) {
  3. const strs = dispositionInfo.split(";");
  4. let filename = "";
  5. strs
  6. .map((item) => item.split("="))
  7. .find((item) => {
  8. if (item[0].indexOf("filename") !== -1) {
  9. filename = decodeURI(item[1]);
  10. }
  11. });
  12. return filename;
  13. }
  14. /**
  15. * 通过api下载文件
  16. * @param {AxiosPromise} fetchFunc 下载接口
  17. * @param {String}} fileName 文件名
  18. * @returns Promise<Boolean>
  19. */
  20. export async function downloadByApi(fetchFunc, fileName) {
  21. let errorInfo = null;
  22. const res = await fetchFunc().catch((e) => {
  23. errorInfo = e;
  24. });
  25. // 展示后台错误信息
  26. if (errorInfo) {
  27. if (errorInfo.response && objTypeOf(errorInfo.response.data) === "blob") {
  28. const res = await blobToText(errorInfo.response.data).catch(() => {});
  29. if (!res) return Promise.reject("下载失败!");
  30. const resJson = JSON.parse(res);
  31. return Promise.reject(resJson.desc);
  32. } else {
  33. return Promise.reject("下载失败!");
  34. }
  35. }
  36. const filename =
  37. fileName || parseDownloadFilename(res.headers["content-disposition"]);
  38. downloadByBlob(new Blob([res.data]), filename);
  39. return true;
  40. }
  41. /**
  42. * 下载blob
  43. * @param {Blob} data blob对象
  44. * @param {String} filename 文件名
  45. */
  46. export function downloadByBlob(data, filename) {
  47. const blobUrl = window.URL.createObjectURL(data);
  48. downloadByUrl(blobUrl, filename);
  49. }
  50. /**
  51. * 下载url
  52. * @param {String} url 文件下载地址
  53. * @param {String}} filename 文件名
  54. */
  55. export function downloadByUrl(url, filename) {
  56. const tempLink = document.createElement("a");
  57. tempLink.style.display = "none";
  58. tempLink.href = url;
  59. const fileName = filename || url.split("/").pop().split("?")[0];
  60. tempLink.setAttribute("download", fileName);
  61. if (tempLink.download === "undefined") {
  62. tempLink.setAttribute("target", "_blank");
  63. }
  64. document.body.appendChild(tempLink);
  65. tempLink.click();
  66. document.body.removeChild(tempLink);
  67. window.URL.revokeObjectURL(url);
  68. }
  69. /**
  70. * 下载图片
  71. * @param {String} url 图片地址
  72. * @param {String} filename 下载的文件名
  73. * @returns Promise<Boolean>
  74. */
  75. export function downloadByImgUrl(url, filename) {
  76. return new Promise((resolve, reject) => {
  77. const img = new Image();
  78. // 跨域支持,需要服务端辅助配置
  79. // img.crossOrigin = "";
  80. img.onload = function () {
  81. const canvas = document.createElement("canvas");
  82. const ctx = canvas.getContext("2d");
  83. if (!canvas || !ctx) {
  84. return reject("不支持下载!");
  85. }
  86. canvas.width = img.width;
  87. canvas.height = img.height;
  88. ctx.drawImage(img, 0, 0);
  89. canvas.toBlob((blob) => {
  90. downloadByBlob(blob, filename);
  91. resolve(true);
  92. });
  93. };
  94. img.onerror = function (e) {
  95. reject(e);
  96. };
  97. img.src = url;
  98. });
  99. }