关于vux+axios使用FormData 实现上传文件功能

泄露秘密 提交于 2020-01-12 08:34:47

前言

在搭建网站时,上传文件都是一个不可避免的需求。为了实现上传文件功能,需要使用<input type="file"/> 、formData数据和ajax(axios)来实现。

实现选取本地文件

实现文件上传功能的第一步就是要实现选取本地文件功能。通过<input type="file"/> 就可以实现选取本地文件功能。

<body>
  <input id="file type="file" />
</body>

页面效果:
在这里插入图片描述
可以看到,上面的页面效果并不是很好看。然而,当你想着着手去改动该input标签样式时,你会发现非常的难以实现所要的效果。对此,一般的做法就是,新建一个button,通过button的click事件去触发<input type="file"/>的click事件。

数据封装

通过<input type="file"/>控件,我们可以获取到所要上传的文件。但是要将其传给后端我们还需将文件数据进行封装。这一步要就要借助FormData了。做法如下:

/*
* 当input的值发生改变时触发
**/
changeFile() {
  const file = document.querySelector("#file").files[0];   // 获取需要上传的文件数据
  if (file) {
    let fd = new FormData();
    fd.append("file", file);
  }
},

使用 axios 上传文件

/*
* 使用 axios的post方法上传文件
**/
upload(formdata) {
  let that = this;
  that.axios
    .post("/file/upload", formdata)
    .then(res => {
    })
    .catch(err => {
    });
},

以上就是上传文件前端的全部代码了。但是有几点需要注意的:

注意事项:

1. 同时上传其他数据

有时候,我们上传数据是不单单需要文件数据,还需要一些额外的数据(如:用户名等)。这是我们就不能像以往的post用法那样直接在添加参数到请求body里了。因为在body里添加而外参数,会导致后端无法获取解析文件数据(具体原因请看第二项注意事项)。正常做法是把额外的数据也添加到FormData里面。代码如下:

/*
* 当input的值发生改变时触发
**/
changeFile(name) {
  const file = document.querySelector("#file").files[0];   // 获取需要上传的文件数据
  if (file) {
    let fd = new FormData();
    fd.append("file", file);
    fd.append("name", name);	// 用户名
  }
},

2.切忌设置Content-Type

向后端传输FormData数据,Content-Type 的类型一定得是 multipart/form-data。此外还需要规定一个内容分割符用于分割请求体中不同参数的内容 (详细说明请打开该链接查看)。下面是一个能正常传输 FormData 数据的请求头:

在这里插入图片描述可以看到 Content-Type 后面有一串复杂的代码。那个就是内容分割符。所以手动设置这些是很麻烦的。好在,如果我们对请求的 Content-Type 进行手动设置,浏览器会自动识别 FormData数据并设置 Content-Type 。

这也就是为什么不要设置 Content-Type 的原因了。在第一点我提及过上传文件的请求体添加其他参数时必须要添加到FormData。这是因为如果请求boby里如果存在非FormData数据类型时,浏览器就不会识别数据FormData。也就是,Content-Type不会自动添加为multipart/form-data,而是变成了application/json。这样一来,后端就拿不到文件数据了。

在使用axios时,我们有时会添加拦截器。在进行拦截器设置时也要考虑到FormData。如果是FormData数据就不要设置Content-Type了。

结语

文件上传需要用到<input type="file"/> 、FormData数据类型,在向后端发送数据是切忌设置 Content-Type 。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!