吃透前端文件上传与文件相关操作

最近在学文件上传的操作,所以想把学习到东西写成一文章

这片文章是我以小白视角 慢慢学习并熟悉前端文件相关操作的流程总结出来的

前端文件上传 我首先想到是

html 复制代码
<input type="file">选择文件</input>

如果我们想限制上传文件的格式,大小或进行裁剪分片上传

##如何对文件上传进行操作呢

查阅mdn文档 发现三个可用于type="file"的属性

accept 文件上传控件中预期文件类型的提示

capture 文件上传控件中媒体捕获方法的提示

  • capture="camera":用户将直接进入摄像头捕获界面,可以拍摄照片或录制视频。
  • capture="user":用户将进入相册,可以从相册中选JJ择照片或视频。
    multiple 布尔值。是否允许多个值 默认为false
html 复制代码
<input type="file" accept="image/*" multiple>选择文件</input>

额。。。。。。好像并没有解决问题

换另一个办法,可以使用 File 对象的属性

html 复制代码
<input type="file" id="fileInput" ></input>

<script>

const fileInput = document.getElementById('fileInput');

fileInput.addEventListener('change', function(event) {

const file = event.target.files[0];

console.log('文件名:', file.name);

console.log('文件大小:', file.size);

console.log('文件类型:', file.type);

});

</script>

这次获取到可以操作对象的属性

这下可以实现一些简单的需求 比如约束文件格式,约束文件大小

js 复制代码
 if(file.size > 10 * 1024 *1024){

 alert('不能超过10M')

 }
 if(file.type !=='image/jpeg'){

 alert('必须为jpeg图片')

 }

那么如何实现文件内容的操作呢

想要操作文件的内容 先获取文件的内容

如何读取文件内容

JS中提供了API。可以使用 FileReader对象读取文件内容,然后进行处理。,常见的转换方法包括readAsText()readAsDataURL(),readAsArrayBuffer()

如何使用

  • 如果需要将文件内容解析为文本形式,可以使用 readAsText(file)
  • 如果需要处理文件的二进制数据,可以使用 readAsArrayBuffer(file)
  • 如果需要在页面中显示文件内容或生成可用于展示的 URL,可以使用 readAsDataURL(file)
js 复制代码
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function(event) {
const file = event.target.files[0]

const reader = new FileReader();

//解析成 Base64

reader.readAsDataURL(file);

JJreader.onload = function(e) {

const fileContent = e.target.result;
//const fileContent= reader.result;

console.log('文件内容:', fileContent);

};

});

前端给后端传输文件的格式

前端给后端的文件一般都是二进制blob传输或base64传输格式,前端给后端上传文件

那么什么是blob对象呢
Blob对象是用来表示二进制数据的一个接口,可以存储大量的二进制数据

mdn上解释

要从其他非 blob 对象和数据构造一个 Blob,请使用 Blob 构造函数。要创建一个 blob 数据的子集 blob,请使用 slice() 方法。

语法 new Blob(array, options)

File对象

new File()

new File(bits, name[, options])

bits一个包含ArrayBuffer,ArrayBufferView,Blob,或者 DOMString 对象的Array --- 或者任何这些对象的组合。这是 UTF-8 编码的文件内容。

现在可以运用了解的知识 可以做一个缩略图了用vue实现下

vue 复制代码
<template>
<input type="file" name="file" @change="fileChange">选择文件</input>
<img :src="imgbase64" style="width:800px"/>
</template>
<script setup>
const imgbase64 = ref()
const fileChange = (e:any) => {
//这最好做个浅拷贝 直接在原对象上面操作不好
let file = e.target.file
let _sliceBlob = new Blob([__file]).slice(0,5000)
let _sliceFile = new File([_sliceBlob],"text.jpeg")
let fr = new FileReader()
// 转换成base64
fr.readAsDataURL(_sliceFile)
fr.onload = function(){
imgbase64.value = fr.result
}
}
</script>

如何上传到后端

查询mdn
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。

你可以使用FormData.append来添加键/值对到表单里面

js 复制代码
Submitbtn.addEventListener('click',() => {

let _formData = new FormData()

let data = _formData.append(_file.name+'file',_file)

axios.post("/xx",data)

})

接下来代码用Vue实现 基础文件上传操作已经完成 接下来是些小功能

如何实现多文件上传

正常方案应该是直接在input里面加入multiple

xml 复制代码
<input type="file" multiple></input>

这样就可以直接ctrl+鼠标左键就可以多选 但明显不符合日常多文件上传的习惯 有些人喜欢一个一个选 而且需要把多文件上传的名字 "两个文件" 改成 两个文件各自名字好些

接下来实现一波 无非就是定义一个数组,将之前的值存里面

xml 复制代码
<template>

<input type="file" name="file" @change="fileChange" multiple >选择文件</input>

<span v-for="item in imgList" :key="item">{{item.name}} </span>

<button @click="sumbit">文件按钮</button>

</template>
<script setup lang="ts">
import { ref } from 'vue';
const imgList = ref([])
let file = e.target.files[0]

__file = file

e.target.files.length > 1 ? imgList.value.push(...e.target.files) : imgList.value.push(e.target.files[0])	

const sumbit =async () => {

imgList.value.forEach((item) => {

let _formData = new FormData()

console.log(item)

let data = _formData.append(item.name + 'file',item)

axios.post("/xx",data)

})
</script>

多文件上传就实现了

有些时候上传文件过大,为了加快效率可以使用且切片上传

大文件切片上传

js 复制代码
//可以做进度条
let precent = ref(0)
const sumbit =async () => {

let allSize = __file.size

let size = 1 * 1024 * 1024

let current = 0 ;

while(current < allSize){

const formData = new FormData()

let data = formData.append(__file.name,__file.slice(current,current + size))

axios.post("/xxxx",data)

precent.value = Math.min((current/allSize),100)

current += size

}

}
相关推荐
zhougl9961 小时前
html处理Base文件流
linux·前端·html
花花鱼1 小时前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_1 小时前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo3 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)3 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之4 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端4 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡4 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木5 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!6 小时前
优选算法系列(5.位运算)
java·前端·c++·算法