WordPress手机站插件,wordpress 购物 插件,好用的网页制作软件,世界500强企业排名一览表最新最近在学文件上传的操作,所以想把学习到东西写成一文章 这片文章是我以小白视角 慢慢学习并熟悉前端文件相关操作的流程总结出来的 前端文件上传 我首先想到是
input typefile**选择文件**/input如果我们想限制上传文件的格式,大小或进行裁剪分片…最近在学文件上传的操作,所以想把学习到东西写成一文章 这片文章是我以小白视角 慢慢学习并熟悉前端文件相关操作的流程总结出来的 前端文件上传 我首先想到是
input typefile**选择文件**/input如果我们想限制上传文件的格式,大小或进行裁剪分片上传
如何对文件上传进行操作呢
查阅mdn文档 发现三个可用于type“file”的属性 accept 文件上传控件中预期文件类型的提示 capture 文件上传控件中媒体捕获方法的提示
capturecamera用户将直接进入摄像头捕获界面可以拍摄照片或录制视频。captureuser用户将进入相册可以从相册中选择照片或视频。multiple 布尔值。是否允许多个值 默认为false
input typefile acceptimage/* multiple选择文件/input额。。。。。。好像并没有解决问题 换另一个办法,可以使用 File 对象的属性
input typefile idfileInput /inputscriptconst 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这次获取到可以操作对象的属性 这下可以实现一些简单的需求 比如约束文件格式,约束文件大小 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)。 下列代码用常用的base64举例
const fileInput document.getElementById(fileInput);
fileInput.addEventListener(change, function(event) {
const file event.target.files[0]const reader new FileReader();//解析成 Base64
reader.readAsDataURL(file);reader.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实现下
template
input typefile namefile changefileChange选择文件/input
img :srcimgbase64 stylewidth: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如何上传到后端
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式本接口和此方法都相当简单直接。如果送出时的编码类型被设为 multipart/form-data它会使用和表单一样的格式。 你可以使用FormData.append来添加键/值对到表单里面
Submitbtn.addEventListener(click,() {let _formData new FormData()let data _formData.append(_file.namefile,_file)axios.post(/xx,data)})接下来代码用Vue实现 基础文件上传操作已经完成 接下来是些小功能
如何实现多文件上传
正常方案应该是直接在input里面加入multiple
input typefile multiple/input这样就可以直接ctrl鼠标左键就可以多选 但明显不符合日常多文件上传的习惯 有些人喜欢一个一个选 而且需要把多文件上传的名字 “两个文件” 改成 两个文件各自名字好些 接下来实现一波 无非就是定义一个数组将之前的值存里面
templateinput typefile namefile changefileChange multiple 选择文件/inputspan v-foritem in imgList :keyitem{{item.name}} /spanbutton clicksumbit文件按钮/button/template
script setup langts
import { ref } from vue;
const imgList ref([])
let file e.target.files[0]__file filee.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多文件上传就实现了
大文件切片上传
为什么要切片上传
避免上传超时大文件可能会导致上传时间过长从而触发服务器超时或网络中断。切片上传将大文件分解成小块每块上传时间较短能有效减少超时问题。 支持断点续传如果上传过程中发生错误如网络中断只有当前切片需要重新上传而不是整个文件。这大大减少了重新上传的工作量和时间。 减少内存占用在上传过程中服务器可以逐个处理小块数据减少对内存的需求而不是一次性接收整个大文件。
实现大文件切片上传步骤
1.获取上传文件对象
2.创建分片数据
3.分片数据创建内容
4.调用发送分片的接口!DOCTYPE htmlhtml langenbodyscript srchttps://cdn.jsdelivr.net/npm/spark-md53.0.2/spark-md5.min.js/scriptinput idinputBox typefile multiple/inputscriptvar inputs document.getElementById(inputBox)inputs.onchange async function(){// 获取到上传文件对象let file inputs.files[0]//创建分片数据let chunks createChunk(file,50*1024*1024)//分片数据创建内容let res await createhash(chunks)//调用发送分片的接口uploadChunk(chunks,res,file.name)}function createChunk(file, chunkSize){const result []for(let i0; i file.size; ichunkSize){result.push(file.slice(i, i chunkSize))}return result}function createhash(chunks){return new Promise((resolve) {let spark new SparkMD5()function _read(i){if(i chunks[i]){resolve(spark.end())return}//获取当前其中的一个片段let blob chunks[i]// 创建一个FileReader对象let reader new FileReader()reader.onload e {let bytes e.target.resultspark.append(bytes)_read(i1)}reader.readAsArrayBuffer(blob)read(i1)}_read(0)})}function uploadChunk(chunks,hash,fileName){let taskArr []chunks.forEach((chunk,index) {let formdata new FormData()formdata.append(chunk,chunk)formdata.append(chunkName,${hash}-${index}-${fileName})fromdata.append(fileName,fileName)let task axios.post(http://127.0.0.01/xxx/xxx, fromdata,{headers:{Content-Type::multipart/form-data}})taskArr.push(task)})Promise.all(taskArr).then(() {console.log(通知后端)})}/script/body/html拖拽上传 步骤 设置拖拽区域创建一个可拖拽的区域通常通过设置一个带有边框和中心提示的 HTML 元素来完成。 处理拖拽事件监听拖拽相关事件如 dragenter、dragover、dragleave 和 drop。这些事件帮助你控制拖拽区域的样式变化例如当文件拖入时改变边框颜色并防止默认行为如浏览器默认打开文件。 接下来就是老步骤了
div classdrag-areadiv classiconisvg t1720077078914 classicon viewBox0 0 1024 1024 version1.1 xmlnshttp://www.w3.org/2000/svg p-id3421 width200 height200path dM1022.955204 522.570753c0 100.19191-81.516572 181.698249-181.718715 181.698249l-185.637977 0c-11.2973 0-20.466124-9.168824-20.466124-20.466124 0-11.307533 9.168824-20.466124 20.466124-20.466124l185.637977 0c77.628008 0 140.786467-63.148226 140.786467-140.766001 0-77.423347-62.841234-140.448776-140.203182-140.766001-0.419556 0.030699-0.818645 0.051165-1.217734 0.061398-5.945409 0.143263-11.686157-2.292206-15.687284-6.702656-4.001127-4.400217-5.894244-10.335393-5.167696-16.250102 1.330298-10.806113 1.944282-19.760043 1.944282-28.192086 0-60.763922-23.658839-117.884874-66.617234-160.833035-42.968627-42.968627-100.089579-66.617234-160.843268-66.617234-47.368844 0-92.742241 14.449084-131.208321 41.781592-37.616736 26.738991-65.952084 63.700811-81.925894 106.884332-2.425236 6.538927-8.012488 11.399631-14.827707 12.893658-6.815219 1.483794-13.927197-0.603751-18.859533-5.54632-19.289322-19.330254-44.943608-29.972639-72.245418-29.972639-56.322773 0-102.146425 45.813419-102.146425 102.125959 0 0.317225 0.040932 0.982374 0.092098 1.627057 0.061398 0.920976 0.122797 1.831718 0.153496 2.762927 0.337691 9.465582-5.863545 17.928325-15.001669 20.455891-32.356942 8.933463-61.541635 28.550243-82.181721 55.217602-21.305235 27.516704-32.571836 60.508096-32.571836 95.41307 0 86.244246 70.188572 156.422585 156.443052 156.422585l169.981393 0c11.2973 0 20.466124 9.15859 20.466124 20.466124 0 11.2973-9.168824 20.466124-20.466124 20.466124l-169.981393 0c-108.828614 0-197.3753-88.536452-197.3753-197.354833 0-44.053332 14.223956-85.712127 41.126676-120.473839 22.809495-29.460985 53.897537-52.086285 88.710414-64.816215 5.065366-74.322729 67.149353-133.2447 142.751215-133.2447 28.386514 0 55.504128 8.217149 78.651314 23.52581 19.657712-39.868009 48.842405-74.169233 85.497233-100.212376 45.434795-32.295544 99.004875-49.354058 154.918325-49.354058 71.692832 0 139.087778 27.915793 189.782368 78.600149 50.694589 50.694589 78.610382 118.089535 78.610382 189.782368 0 3.704368-0.102331 7.470135-0.296759 11.368932C952.633602 352.568894 1022.955204 429.511287 1022.955204 522.570753z p-id3422 fill#cdcdcd/pathpath dM629.258611 820.711014l-102.023628 102.013395c-3.990894 4.001127-9.230222 5.996574-14.46955 5.996574s-10.478655-1.995447-14.46955-5.996574l-102.023628-102.013395c-7.992021-7.992021-7.992021-20.947078 0-28.939099s20.947078-8.002254 28.939099 0l67.087954 67.077721 0-358.699522c0-11.2973 9.15859-20.466124 20.466124-20.466124 11.307533 0 20.466124 9.168824 20.466124 20.466124l0 358.699522 67.087954-67.077721c7.992021-8.002254 20.947078-7.992021 28.939099 0S637.250632 812.718993 629.258611 820.711014z p-id3423 fill#cdcdcd/path/svg/i/divheaderDrag Drop to Upload File/headerspanOR/spanbuttonBrowse file/buttoninput typefile hidden/divjs部分
const dragArea document.querySelector(.drag-area)dragText dragArea.querySelector(header)button dragArea.querySelector(button)input dragArea.querySelector(input)let file;button.onclick function () {input.click()}input.addEventListener(change,() {file this.files[0]showFile()})dragArea.addEventListener(dragover,(event) {event.preventDefault();dragArea.classList.add(active)})dragArea.addEventListener(dragleave,() {console.log(222)dragArea.classList.remove(active)})dragArea.addEventListener(drop,(event) {event.preventDefault();console.log(222)file event.dataTransfer.files[0]showFile()})function showFile(){let fileType file.typeconst validFiletype [image/jpeg,image/jpg,image/png]if(validFiletype.includes(fileType)){let fileReader new FileReader()fileReader.onload () {fileReader fileReader.result;let imgTag img src${fileReader} altdragArea.innerHTML imgTag}fileReader.readAsDataURL(file)}else{console.log(不规则的)}}
css部分
*{margin:0;padding:0;box-sizing: border-box;}body{display:flex;align-items: center;justify-content: center;min-height: 100vh;background-color: #5256ad;}.drag-area{border: 2px dashed #fff;height: 500px;width:700px;border-radius: 5px;display:flex;align-items: center;justify-content: center;flex-direction:column;}.drag-area .active {border: 2px solid #fff;}.drag-area .icon{width:100px;height:100px;}.drag-area header {font-size:30px;font-weight:500;color:#fff;}.drag-area span{font-size:25px;font-weight:500;color:#fff;margin:10px 0 15px 0 ;}.drag-area button{padding:10px 25px;font-size:20px;font-weight:500;border:none;outline:none;background-color: #fff;color:#5256ad;border-radius: 5px;cursor:pointer}.drag-area img {height:100%;width:100%;object-fit: cover;border-radius: 5px;}如果对你有所帮助的话就点个关注吧