Skip to content

上传文件

基础知识点

传统模式

使用form表单提交,提交的路径是action,enctype设置为multipart/form-data

js
    <form method="post" action="http://123.57.138.48/api/upload/" enctype="multipart/form-data" >
      <input type="file"/>
      <button type="submit">submit</button>
    </form>

现在流行模式

使用axios模拟form表单提交,核心还是使用input,绑定change方法,当值改变的时候触发

vue
<template>
  <input
    ref="fileInput"
    type="file"
    @change="handleFileChange"
  />
  
</template>
<script lang="ts">
  import { defineComponent } from 'vue'
  import axios from 'axios'

  export default defineComponent({
    name: 'Uploader',
    setup() {
      const handleFileChange = (e: Event) => {
        const target = e.target as HTMLInputElement
        const files = target.files
        if (files) {
          const uploadFile = files[0]
          const formData = new FormData()
          formData.append(uploadFile.name, uploadFile)
          axios.post('http://123.57.138.48/api/upload/', formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }).then(resp => {
            console.log(resp.data)
          })
        }
      }
      return {
        handleFileChange
      }
    }
  })
</script>

element-ui的upload源码:https://github.com/element-plus/element-plus/tree/dev/packages/components/upload

element-ui库中的upload组件,也是通过input上传文件,将文件放到FormData中发送到后端

可以参考的项目lego-zb中的styled-uploader、uploader组件,这里面实现了基本的上传功能

1、e.target.files是FileList对象 文档 FileList是一个类数组,不是真的数组

2、files[索引]拿到对应的文件,它是File对象 文档

3、传递数据必须把数据放到FormData中 文档

上传遇到的问题

1、formdata里字段的值为file或者图片,而且值有多个,不能放在数组里,然后赋值。而应该给当前字段多次赋值

错误示例:这种方式传递会报错

js
const formData = new FormData()
const fileList = []
fileList.push(file2)
fileList.push(file3)
formData.append('file', JSON.stringify(fileList))

正确示例:

js
const formData = new FormData()
formData.append('file', file2)
formData.append('file', file3)

后端Java接收代码:

java
@RequestMapping(value = "upload.do")
public void upload(@RequestParam MultipartFile[] file,String name) {
    System.out.println(Arrays.toString(file));
    System.out.println(name);
}

使用MultipartFile类型,如果当前参数有多个值,就用MultipartFile[]

Js相关方法

将base64格式转换成Blob方法(可以把base64格式转换成Blob格式,保存到formdata里传给后端)

js
/**
 * 将以base64的图片url数据转换为Blob
 */
export function convertBase64UrlToBlob(urlData) {
  const bytes = window.atob(urlData.split(',')[1]) // 去掉url的头,并转换为byte
  // 处理异常,将ascii码小于0的转换为大于0
  const ab = new ArrayBuffer(bytes.length)
  const ia = new Uint8Array(ab)
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i)
  }

  return new Blob([ab], {
    type: 'image/png'
  })
}

element-ui的上传组件

使用element-ui的组件手动上传文件

html
<el-upload
  class="avatar-uploader"
  :limit="1"
  accept=".jpg,.jpeg,.png"
  drag
  action="#"
  :file-list="logoList"
  :show-file-list="false"
  :auto-upload="false"
  :on-change="logoUploader"
>
  <el-button type="primary">点击上传</el-button>
</el-upload>

文档地址:上传组件

备注

上面是简单版,auto-upload设置为false(不自动上传文件), 使用on-change获取上传的文件信息,在这个方法里,将文件信息进程处理后调用接口,传给后端

如有转载或 CV 的请标注本站原文地址