赞
踩
一、前端文件上传有两种思路:
二、与文件相关的对象
三、file参数、blob切割文件、FileReader将文件转成base64,浓缩图/文本预览:
<template> <div> <input type="file" name="file" @change="fileChange" /> <!-- 缩略图,文本预览 --> <img style="width:200px;" :src="imgbase64" /> <button @click="submit">提交</button> </div> </template> <script> import axios from "axios" import { fstat } from "fs"; let _fileObj; export default { name: 'HelloWorld', data() { return { imgbase64: "", } }, methods: { fileChange(e) { let file = e.target.files[0]// files是个数组 _fileObj = file; // file常用属性:size(大小)、type(类型)、name(文件名) if (file.size > 10 * 24 * 24) { alert("文件不能大于十兆") } if (file.type !== 'video/mp4') { alert("必须是mp4") } // 使用blob的slice方法可以切割文件 let _sliceBlob = new Blob([file]).slice(0, 5000);// 切割二进制的0-5000位 // 将切割后的Blob对象转成File对象(第二个参数是文件名),之后就可以上传切割后的File对象 let _sliceFile = new File([_sliceBlob], "test.png"); //将File对象或者Blob对象转成base64或text let fr = new FileReader(); fr.readAsDataURL(_sliceFile);// readAsDataURL是转成base64的方法 let self = this; fr.onload = function () { // base64是异步的转换,通过onload方法获得转换结果 self.imgbase64 = fr.result// 直接将转换结果赋值给img的src,设置src的大小即可获得浓缩图 console.log(fr.result)// 打印结果见下图一 } }, async submit() { // 这部分的代码后面讲 let _formData = new FormData(); _formData.append("user", "asdasd"); _formData.append("file", _fileObj) axios.post("/xx", _formData); } } } } </script>
四、formData:不仅可以搭载文件,还可以搭载文字、input的其他输入
<form action="xxx" method="post">默认情况下提交为query参数</from>
<form action="xxx" method="post" enctype="multipart/form-data">enctype指定提交为formData</from>
五、文件上传:将blob转成FormData上传
async submit() {
let _formData = new FormData();
_formData.append("user", "asdasd");
_formData.append("file", _fileObj)
axios.post("/xx", _formData);
}
通过查看网络可以发现:
七、具体功能
<template> <div> <input type="file" name="file" @change="fileChange" multiple /> <span v-for="item in imgList">{{ item.name }}</span> <button @click="submit">提交</button> </div> </template> <script> import axios from "axios" import { fstat } from "fs"; let _fileObj; export default { name: 'HelloWorld', data() { return { imgList: [], } }, methods: { fileChange(e) { //多文件上传 // multiple的多文件上传其实很不友好,需要用户在选择文件时按住ctrl多选,否则就会变成单选 // 所以使用imgList数组将用户每次选择的内容都push进去 if (e.target.files.length > 1) { this.imgList.concat(e.target.files) } else { this.imgList.push(e.target.files[0]); } //切片上传 _fileObj = e.target.files[0] }, async submit() { // 遍历,一个一个上传 this.imgList.forEach((item) => { let _formData = new FormData(); _formData.append(item.name + "file", item) axios.post("/xx", _formData); }) } } } </script>
<template> <div> <input type="file" name="file" @change="fileChange" multiple /> <div>{{ precent }}%</div> <button @click="submit">提交</button> </div> </template> <script> import axios from "axios" import { fstat } from "fs"; let _fileObj; export default { name: 'HelloWorld', data() { return { precent: 0 } }, methods: { fileChange(e) { //切片上传,在上传的时候进行切片,文件改变时只赋值 _fileObj = e.target.files[0] }, async submit() { let size = 2 * 1024 * 1024;// 每次切片的大小,片为2m let fileSize = _fileObj.size; let current = 0;// 当前已经传了多少 // 断点续传,永久记录中断的地方,下次上传时直接从断点开始传 //localStorage.setItem(_fileObj.name, current); while (current < fileSize) { let _formData = new FormData(); _formData.append(_fileObj.name, _fileObj.slice(current, current + size)) await axios.post("http://localhost:4000/upload",_formData) // 进度条可以用axios的onUploadProgress方法,且发送切片时可以并行发送请求,后续可以自行优化 this.precent = Math.min((current / fileSize) * 100, 100) current += size; } } } } </script>
File System Access API 允许直接读取、写入或保存对用户设备上的文件和文件夹的更改。从 Chrome 86 开始支持 File System Access API,目前只有基于 Chromium 系列的浏览器全面支持,Safari 部分支持(支持读取,不支持写入和保存),而 Firefox 未支持。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。