目录
上传
下载
get
post
对象/文件流
download处理返回
文件流
axios.post
封装axios
后端直接返回文件流,打开下载文件是 [object Object],将res改成res.data即可
1.请求设置类型responseType: 'blob'(如果没有设置,打开文件会是乱码)
2.若有请求拦截(直接返回即可)
3.download
4.请求下载
相关基础
get和post请求
Response.text()以Promise对象获取响应的文本数据
decodeURIComponent() 解码
escape() 编码
blob
MIME
上传
submitAddFile(){
            var formData = new FormData();
            formData.append('num', this.addType);
            formData.append('linkId',this.addId);
            formData.append('rfilename',this.addFileName);
            for(var i=0;i<this.addArr.length;i++){
                formData.append('fileUpload',this.addArr[i]);
            }
          let config = {
            headers: {
              'Content-Type': 'multipart/form-data',
              'Authorization': this.token
            }
          };
          this.axios.post(apidate.uploadEnclosure,formData,config)
            .then((response) => {
                if(response.data.info=="success"){this.$message({
                        type: 'success',
                        message: '附件上传成功!'
                    });
                }
            })
        }
vue 实现文件上传、下载的方法 - 掘金
下载
get
//静态a标签
<a :href='"/user/downloadExcel"' >下载模板</a>
//动态创建a标签:
<div name="downloadfile" onclick="downloadExcel()">下载</div>
function downloadExcel() {
    let a = document.createElement('a')
    a.href ="/user/downloadExcel"
    a.click();
} 
//window
 function downloadExcel() {
    window.location.href = "/tUserHyRights/downloadUsersUrl";
} 
post
对象/文件流
download处理返回
export const download= (response: { data?: any; config?: any }) => {
  console.log("response", response);
return new Promise((resolve, reject) => {
  const fileReader = new FileReader();
  fileReader.onload = function () {
    try {
      console.log("result:", this.result);
      const jsonData = JSON.parse((this as any).result); // 成功 说明是普通对象数据
      if (jsonData?.code !== 200) {
        errorMsgTips(jsonData?.message ?? "请求失败");
        reject(jsonData);
      }
    } catch (err) {
      // 解析成对象失败,说明是正常的文件流
      // responseType为blob,以便接收二进制数据。
      const blob = new Blob([response.data]);
      // 本地保存文件
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      const filename = response?.config.headers?.["content-disposition"]
        ?.split("filename*=")?.[1]
        ?.substr(7);
      link.setAttribute("download", decodeURI(filename));
      document.body.appendChild(link);
      link.click();
      resolve(response.data);
    }
  };
  fileReader.readAsText(response.data);
});
文件流
axios.post
// Vue组件中的方法
methods: {
  downloadFile() {
    axios.post('/api/download', { /* 请求参数 */ }, { responseType: 'blob' })
      .then(response => {
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement('a');
        link.style.display = 'none'
        link.href = url;
         const filename = response?.config.headers?.["content-disposition"]
           ?.split("filename*=")?.[1]
           ?.substr(7);
         link.setAttribute("download", decodeURI(filename));// 指定下载后的文件名,防跳转
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      })
      .catch(error => {
        // 处理错误
        console.error(error);
      });
  }
}
从响应头中提取文件名:响应头的Content-Disposition字段的值具有形式类似于filename*=UTF-8''example-file.txt,并提取出文件名example-file.txt。
封装axios
后端直接返回文件流,打开下载文件是 [object Object],将res改成res.data即可

1.请求设置类型responseType: 'blob'(如果没有设置,打开文件会是乱码)
import request from '@/utils/request'
const baseUrl = process.env.NODE_ENV === 'development' ? '/test' : ''
const mock = false
export const postQuery = (params:string) => {
  const url = mock ? `${baseUrl}/xxx:8081/otherIndexUpload/${params}`: `${baseUrl}/otherIndexUpload/${params}`
  console.log('post: ',url)
  return request({url,method:'post', responseType: 'blob'})
}
return request({
    url: '/data/wos/download',
    method: 'post',
    data,
    responseType: 'blob',
    timeout: 3000000,
    onDownloadProgress: function (progressEvent: any) {
      // 处理原生进度事件
      store.state.percent = ((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
      console.log(`下载进度:${store.state.percent}`)
      if (Number(store.state.percent) == 100) {
        store.commit('changeProgress')
      }
    }
  })2.若有请求拦截(直接返回即可)
import service from 'axios'
// 响应拦截器
service.interceptors.response.use(
  (response: { data: any; config: any }) => {
    const resData = response.data || {}
    if (response.config.responseType === 'blob') {
      return response
    }..
  },
  (error: any) => {
...
  }
)
export default service
3.download
export const download = (res: any) => {
  var blob = new Blob([res.data], {
    type: "application/vnd.ms-excel;charset=utf-8",
  });
  var url = window.URL.createObjectURL(blob);
  var aLink = document.createElement("a");
  aLink.style.display = "none";
  //指定文件名,防止跳转
  aLink.download =decodeURIComponent(escape(res?.headers?.["content-disposition"]?.split("filename=")?.[1]))
  aLink.href = url;
  document.body.appendChild(aLink);
  aLink.click();
  document.body.removeChild(aLink);
}4.请求下载
toDownloadTemplate() {
    console.log('下载模板')
    API.postQuery(`downloadTemplate/${this.fileId}`).then((res: any) => {
      if (res.data.type==="application/vnd.ms-excel") {
        download(res);
      } else {
        res.data.text().then((res: any) => {
          this.$message.warning(JSON.parse(res).msg)
        })
      }
    })
  }相关基础
get和post请求
POST:用于传输信息给服务器,功能与 GET 类似,但一般推荐使用 POST 方式;
GET: 用于请求访问已经被 URI(统一资源标识符)识别的资源,可以通过 URL 传参给服务器;
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
因为GET参数通过URL传递,POST放在Request body中
 所以GET参数暴露在地址栏不安全,POST放在报文内部更安全
所以超链接下载是get请求
Response.text()以Promise对象获取响应的文本数据
适用于requst指定responseType后,但响应的content-type有的不适合该responseType

fetch('https://example.com/api/data')
  .then(response => response.text())
  .then(textData => {
    console.log(textData); // 输出响应的文本数据
  })
  .catch(error => {
    console.error(error);
  });
decodeURIComponent() 解码
 
函数对编码后的字符串进行解码,显示正常内容
escape() 编码
 
函数对乱码字符串进行编码,以确保特殊字符(如中文)按照 UTF-8 进行编码。
blob
二进制大对象(Binary Large Object)。Blob是存储二进制数据的数据类型,例如图像、音频和视频文件等
MIME
多用途互联网邮件扩展(Multipurpose Internet Mail Extensions)表示传输的文件的性质和格式。在HTTP头部或其他协议中指定一个特定的字符串,来标识文件的类型。
主类型表示文件的大类别,
"application"表示应用程序类型,
"text"表示文本类型,
"image"表示图像类型等。
子类型表示具体的文件格式,
"plain"表示纯文本,
"vnd"表示自定义类型
"vnd.ms-excel":Microsoft Excel电子表格文件。


















