上传文件el-upload

<el-upload ref="fileUpload"
           class="upload-demo"
           action="upLoadingUrl"
           :before-upload="beforeUpload"
           :before-remove="beforeRemove"
           :on-success="onSuccess"
           :on-change="onchange"
           :on-remove="onRemove"
           :auto-upload="false"
           :fileList="fileList"
           :http-request="onUpload">
	xxxx
</el-upload>

手动触发,用el-upload组件的this.$refs['fileUpload'].submit() 触发http-request函数:

onUpload (file) {
  console.log('onUpload-custom:file:', file)

  let formData = new FormData()
  formData.append(file.filename, file.file, file.file.name)
  
  api.onUploadingFile(this.curCopyIds, formData).then(res => {
    // xxx
  })
},

或者手动执行http-request函数:
click后,执行函数

// change的时候,存下来File
onchange (file, fileList) {
  console.log('onchange',file,fileList)
    this.fileContent = file // 记录file文件流内容
},

// 手动触发按钮,且不用this.$refs['fileUpload'].submit(),直接用自定义函数。
confirmImport () {
    this.onUpload(this.fileContent)
},

在这里插入图片描述

上传报错

下载文件的时候,指定了文件类型为.xlsx,然后上传的时候报错。

"msg": "The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents. You need to call a different part of POI to process this data (eg HSSF instead of XSSF)",

接口中指定文件为.xls格式,所以 改为.xlsx可能破了文件内容(下载模版可以正常打开,格式也ok),但是上传会报错。 ⇒ 接口让 默认.xls即可,暂时不管.xlsx的。

下面这个使用了new Blob:

/**
 * 下载模板
 */
async downloadTemp (e) {
  e.stopPropagation()

  let params = {}
  let res = await deviceMappingDownloadTemp(params) // 获取到文件流
  console.log('下载模版res:', res)  // Blob

  const blob = new Blob([res])
  const blobUrl = window.URL.createObjectURL(blob)
  let a = document.createElement('a')
  a.download = `能源IOT设备映射批量导入模板.xls` // 不指定后缀的话,就是.txt的了。
  a.href = blobUrl
  a.click()
  URL.revokeObjectURL(a.href) // 释放
  // document.body.removeChild(a)
},

上面为什么要指定文件后缀?
接口返回的res是一个Blob,为什么还需要new Blob指定类型?

场景一:我们可以不要new Blob,此时window.URL.createObjectURL(res),那么文件不指定文件类型即可。

场景二:如果 使用了new Blob,默认就指定了类型(new Blob第二个参数就是指定类型的)

// 指定了blob类型,那么也可以不加后缀。
const blob = new Blob([res],{type:'application/vnd.ms-excel'})
const blobUrl = window.URL.createObjectURL(blob)
let a = document.createElement('a')
a.download = `能源IOT设备映射批量导入模板123`

Blob详解

Blob() 构造函数返回一个新的 Blob 对象。blob 的内容由参数数组中给出的值的串联组成。


var aBlob = new Blob( array, options );

const obj = {hello: 'world'};

const blob = new Blob(
  [JSON.stringify(obj, null, 4)],
  {type : 'application/json'}, // application/vnd.ms-excel
);
console.log('文件内容:',blob)

let blobUrl = URL.createObjectURL(blob)
let a = document.createElement('a')
a.download = `文件123`
a.href = blobUrl
a.click()

下载后是一个 json文件,内容为:
在这里插入图片描述

let obj = {
  age: 18,
  sex: '男'
}
let content = JSON.stringify(obj)
// blob类型
let blob = new Blob([content], {
  type: 'application/json'
})
// 将blob转成url
let url = URL.createObjectURL(blob) //blob:null/244bec7f-e3d3-43d5-803e-f98cc5c8117f  =>链接里面的数据就是右边的内容 {"age":18,"sex":"男"}
console.log(url)
// blob转file
let filename = '文件名'
let file = new File([blob], filename, {
  type: 'application/json',
  lastModified: Date.now()
});
// 或者
let file1 = new File([content], filename, {
  type: 'application/json',
  lastModified: Date.now()
});
console.log("文件", file, file1)

在这里插入图片描述

下面这个就是没有用new Blob,直接使用,所以download只指定名字即可,不用加后缀。

/**
 * 下载错误日志
 * 接口返回完整的URL:https://lfrz1.xxxx/abc.xls
 * 直接window.open的话,文件名称是abc这种的,不友好。
 * @param fileUrl
 * @param fileName
 */
download (fileUrl, fileName) {
  const url = fileUrl
  let x = new XMLHttpRequest()
  x.open('GET', url, true)
  x.responseType = 'blob'
  x.onload = function () {
    console.log('日志res:', x.response) // Blob
    let url = window.URL.createObjectURL(x.response)
    let a = document.createElement('a')
    a.href = url
    a.download = fileName
    a.click()
  }
  x.send()
},

// 调用
this.download(this.resultObj.downloadUrl, '错误日志')

Refused to get unsafe header “content-disposition”

后端接口返回文件流的时候,有文件名字,在headers里面,前端获取的时候报错:
Refused to get unsafe header "content-disposition"

 //设置Access-Control-Expose-Headers避免前端调用获取Content-Disposition出现Refused to get unsafe header异常
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(FileBO.getFileName(), "UTF-8"));

// axios:
let dispositionStr = response.headers["content-disposition"];

// 或者 xhr:
xhr.getResponseHeader('content-disposition')

在这里插入图片描述
返回文件名是乱码,需要接口设置一下:
可能是:

response.setHeader("content-disposition","attachment;filename*=utf-8''" + URLEncoder.encode(fileName,"UTF-8"));
// 旧的做法
response.setHeader("content-disposition","attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));

// 新的做法
response.setHeader("content-disposition","attachment;filename*=utf-8''" + URLEncoder.encode(fileName,"UTF-8"));

参考:https://blog.csdn.net/fxtxz2/article/details/107334247

报错:Current request is not a multipart request

背景:手动上传,且通过axios封装接口(不用自己添加headers或者其他参数),但是报错了

在这里插入图片描述

在这里插入图片描述
报错:msg:“Current request is not a multipart request”

接口文档:
在这里插入图片描述

axios封装的默认content-type都是json的…所以el-upload使用axios封装的函数,也是json的,不符合要求啊,自己添加headers:

// 上传: TODO-todo
export const uploadDeviceAxios = params => {
  return instance({
    url: '/device/mgt/batchCreate/import',
    method: 'post',
    data: params,
    headers: {
      // 'Content-Type': 'multipart/form-data'
    }
  });
};

在这里插入图片描述
在这里插入图片描述

上传进度

https://juejin.cn/post/7265239806946590757

https://www.jb51.net/article/259304.htm

// 上传: TODO-todo
export const uploadDeviceAxios = params => {
  return instance({
    url: '/device/mgt/batchCreate/import',
    method: 'post',
    data: params,
    headers: {
      'Content-Type': 'multipart/form-data'
    },
    onUploadProgress: (progressEvent) => {
      console.log('上传e', progressEvent);
      if (progressEvent.lengthComputable) {
        console.log('进度:', Math.round((progressEvent.loaded / progressEvent.total) * 100));
      }
    }
  });
};
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值