前端 Vue 操作文件方法(导出下载、图片压缩、文件上传和转换)

作者 : admin 本文共2809个字,预计阅读时间需要8分钟 发布时间: 2024-06-17 共1人阅读

一、前言

    本文对前端 Vue 项目开发过程中,经常遇到要对文件做一些相关操作,比如:文件导出下载、文件上传、图片压缩、文件转换等一些处理方法进行归纳整理,方便后续查阅和复用。

二、具体内容

1、后端的文件导出接口,返回数据是文件流 blob,转成 url 链接下载

浏览器 F12 调试器打开查看,返回数据长这样的。

前端 Vue 操作文件方法(导出下载、图片压缩、文件上传和转换)插图

注意:记得在定义的接口,响应头部加上 responseType: ‘blob’

import request from '@/utils/request' // 一般基于 axios 封装的 request

export function exportApi(data) { // 导出下载接口
  return request({
    url: '/list/export',
    method: 'post',
    data: data,
    responseType: 'blob',
    timeout: 120000
  })
}

通过 JavaScript 的 window.URL.createObjectURL(new Blob([…])),将 blob 转成可操作的 url 链接,然后模拟 标签链接点击下载。

import { exportApi } from '@/api/index' // 某 vue 文件,引入上一步定义的 api

exportApi().then(res => { // 对应的文件下载 / 导出的方法中,写入该部分代码
  const url = window.URL.createObjectURL(new Blob([res.data])) // 文件流 blob 转成 URL
  const a = document.createElement('a')
  a.style.display = 'none'
  a.href = url
  a.download = '文件名.xlsx' // 自定义下载文件的名称
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
})

2、后端接口返回数据是文件下载的 url 链接

  • 相对第 1 点来说
  • 去掉 responseType: ‘blob’
  • 去掉 window.URL.createObjectURL(new Blob([…]))
  • 写上 a.href = res.data.url
  • 注意:a.download 是 href 属性地址和前端地址同源情况下,才会起作用;否则不同域的情况下,不会起作用,就需要采用文件流 blob 的形式下载来强制修改文件名
  • 直接模拟点击 标签链接下载,其实链接下载还能采用:
// 缺点:体验感不好,屏幕会闪一下,因为这个实际是打开新窗口的然后才关闭
window.open(res.data.url)

3、文件 file 或文件流 blob 转成 base64

后端返回的文件是图片,需要转成 base64(或者第 1 点转成 url 链接)才能在前端展示出来,但这种用的比较少,因为后端一般专门存储图片会直接采用 url 链接的方式。

// file 或者 blob 转成 base64
export function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader()
    fileReader.readAsDataURL(file)
    fileReader.onload = (e) => {
      resolve(e.target.result)
    }
    fileReader.onerror = () => {
      reject(new Error('文件异常'))
    }
  })
}
import { exportApi } from '@/api/index' // 某 vue 文件,引入定义的 api
import { fileToBase64 } from '@/utils/index' // 引入上一步封装的方法

exportApi().then(res => { // 对应的文件下载 / 导出的方法中,写入该部分代码
  const blob = new Blob([res.data])
  fileToBase64(blob).then(str => {
    console.log('转换后的 base64', str)
    // 将获取的 base64 写入 前端 Vue 操作文件方法(导出下载、图片压缩、文件上传和转换)插图(1)

前端 Vue 操作文件方法(导出下载、图片压缩、文件上传和转换)插图(2)

前端 Vue 操作文件方法(导出下载、图片压缩、文件上传和转换)插图(3)

7、前端上传图片或文件,请求后端接口

有重要两点:

  • new FormData()
  • HTTP 的请求头 Content-Type: multipart/form-data; boundary=----...string

前端 Vue 操作文件方法(导出下载、图片压缩、文件上传和转换)插图(4)

    一般前端会通过 axios 请求后端接口,但 axios 发送 HTTP 请求头部里的 Content-Type(内容类型)默认是 application/json;charset=UTF-8,所以默认传参的数据类型是纯文本类型的 JSON 对象,不适合带有文件类型的数据,若需要传参带有文件数据,那么需要把 Content-Type 指定为 multipart/form-data,这样传参可以带上文件类型数据。那么这就需要 JavaScript 提供的 FormData 类型的对象数据,既可以上传文件等二进制数据,也可以上传表单键值对,会转换成为一条信息。示例代码如下:

// 结合上一步的内容,给出的关键代码部分
handleUpload(){ // 确认上传文件
  Toast({
    type: 'loading',
    message: '正在提交...',
    duration: 0,
    forbidClick: true
  })
  let postData = new FormData()
  postData.append('name', 'hxhpg')
  postData.append('gender', 'male')
  postData.append('height', '175cm')
  postData.append('weight', '60kg')
  for (let i = 0; i  { // 某后端接口,通过 axios 封装定义的
    Toast.clear()
    console.log('响应结果', res)
  }).catch(err => {
    Toast.clear()
  })
}

    这里简单说下 application/x-www-form-urlencoded,它是标准的默认编码格式(在原始的 AJAX 中,不是 axios),只能上传键值对,并且键值对都是间隔分开的,不能用于上传文件等二进制数据。当采用 get 方式时,会把表单数据转成一串由 key1=value1&key2=value2&key3=value3... 组成的字符串作为 URL 的参数拼接在后面。当采用 post 方式时,则会把表单数据加入 HTTP 的请求体 body 中。

小结:如果是需要键值形式的数据,有文件时采用 multipart/form-data,没有文件时采用 application/x-www-form-urlencoded


    这是我本人在工作学习中做的一些总结,同时也分享出来给需要的小伙伴哈 ~ 供参考学习,有什么建议也欢迎评论留言,转载请注明出处哈,感谢支持!

本站无任何商业行为
个人在线分享 » 前端 Vue 操作文件方法(导出下载、图片压缩、文件上传和转换)
E-->