ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

那么轻,那么重:图片下载与压缩包下载

2021-12-29 17:02:50  阅读:152  来源: 互联网

标签:那么 const 图片下载 code error message data response 压缩包


0. 缘起

下载,不同文本流有不同下载方式。

1. 图片下载

我直接嗯用以前下载图片的方法,改了下文本流的获取和下载名就敢直接用。结果,呃,直接文件损坏无法打开。

    //导出图片
    exportPic() {
      //canvas的toDataURL()方法返回一个包含图片展示的数据URL
      const dataURL = this.canvas.toDataURL({
        width: this.canvas.width,
        height: this.canvas.height,
        left: 0,
        top: 0,
        format: "png",
      });
      //创建一个a标签,指向图片的URL地址,
      //点击即可下载名为canvas.png的图片
      const link = document.createElement("a");
      link.download = "canvas.png";
      link.href = dataURL;
      //当前文档的Body对象上挂载一个元素,此处为a标签
      //模拟a标签的点击,下载后移除该元素
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    },

2. 压缩包下载的正确操作

2.1 Axios

用的axios,就从它的封装方法里面看。因为涉及到response有没有被更改

const instance = axios.create({
  baseURL,
  timeout: requestTimeout,
  headers: {
    "Content-Type": contentType,
  }
});

instance.interceptors.response.use(
  (response) => {
    if (loadingInstance) loadingInstance.close();

    const { data, config } = response;
    console.log('response: ', response);
    const { code, message } = data;

    let successFlag = response.status;
    // 操作正常Code数组
    const codeVerificationArray = isArray(successCode)
      ? [...successCode]
      : [...[successCode]];
    // 是否操作正常 Old Version
    // if (codeVerificationArray.includes(code)) {
      // New Version ***
    if (successFlag === 200) {
        // Special Blob Type
      if (response.config.responseType === 'blob') {
        return response
      } else {
        return data;
      }
    } else {
      console.log(code, message)
      handleCode(code, message);
      return Promise.reject(
        "请求异常拦截:" +
        JSON.stringify({ url: config.url, code, message }) || "Error"
      );
    }
  },
  (error) => {
    if (loadingInstance) loadingInstance.close();
    const { response, message } = error;
    if (error.response && error.response.data) {
      const { status, data } = response;
      handleCode(status, data.message || message);
      return Promise.reject(error);
    } else {
      let { message } = error;
      if (message === "Network Error") {
        message = "后端接口连接异常";
      }
      if (message.includes("timeout")) {
        message = "后端接口请求超时";
      }
      if (message.includes("Request failed with status code")) {
        const code = message.substr(message.length - 3);
        message = "后端接口" + code + "异常";
      }
      Vue.prototype.$baseMessage(message || `后端接口未知异常`, "error");
      return Promise.reject(error);
    }
  }
);

2.2 Response

注意当成功的时候,之前是直接返回了response里面的data,而我们在获取文件流,要注意responseType得是blob

  // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  responseType: 'json', // 默认的

使用说明 · Axios 中文说明 · 看云 (kancloud.cn)

比如这里,我的下载压缩包方法

// Download MagicBoxVersion 
export function downloadMagicBoxEdition(id) {
  return request({
    url: `/.../export?id=${id}`,
    method: 'POST',
    baseURL: baseURLB,
    responseType: 'blob',
  })
}

2.3 Data

到这一步在下载按钮的download函数里,传个值过去就能获得对应的文件流了。接下来就是如何下载:

    handleExport(row) {
      downloadMagicBoxEdition(row.id).then((res) => {
        console.log(res);
        let blob = new Blob([res.data], {
          type: "application/octet-stream;charset=utf-8",
        }); // res.data就是接口返回的文件流了
        let name = res.headers["content-disposition"];
        let fileName = `${decodeURIComponent(
          name.split(";")[1].split("=")[1]
        )}`.replace("zip", ".zip");
        if ("download" in document.createElement("a")) {
          // 非IE下载
          const elink = document.createElement("a");
          elink.download = fileName;
          elink.style.display = "none";
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href); // 释放URL 对象
          document.body.removeChild(elink);
        } else {
          // IE10+下载
          navigator.msSaveBlob(blob, fileName);
        }
      });
    },

2.4 Title

上面有个fileName,文件名,后端用content-disposition传了过来。

filename

后面是要传送的文件的初始名称的字符串。这个参数总是可选的,而且不能盲目使用:路径信息必须舍掉,同时要进行一定的转换以符合服务器文件系统规则。这个参数主要用来提供展示性信息。当与 Content-Disposition: attachment 一同使用的时候,它被用作"保存为"对话框中呈现给用户的默认文件名。

Content-Disposition - HTTP | MDN (mozilla.org)

        let name = res.headers["content-disposition"];        
		let fileName = `${decodeURIComponent(
          name.split(";")[1].split("=")[1]
        )}`.replace("zip", ".zip");

download函数里面的这段,显然是从头里面取出传递过来的文件名。

PS: 这里一定要注意第一步axios里面封装axios所传递的response是否是完全体,一般都传的response.data,是无法获取到header部分的!

附录

先前写过的上传方法

众里寻他千百度,蓦然回首,那人却在灯火阑珊处:上传の方法 - 乐盘游 - 博客园 (cnblogs.com)

关于文件上传的参考文章,不过直接用el-upload也行

文件上传,搞懂这8种场景就够了 - 掘金 (juejin.cn)

标签:那么,const,图片下载,code,error,message,data,response,压缩包
来源: https://www.cnblogs.com/lepanyou/p/15745680.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有