随着Web应用的普及,文件上传功能成为许多网站和应用不可或缺的一部分。本文整理了个人学习过程中的笔记,为开发者提供全面的了解和实践经验。
单文件上传
在早期的html应用中,都是使用form标签中嵌套来实现文件上传的,具体代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>单文件上传示例</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="fileInput">选择文件:</label>
<input type="file" id="fileInput" name="fileInput">
<button type="submit">上传文件</button>
</form>
</body>
</html>
上述实现方式是最原始也是最简单的代码实现,详细的元素说明如下
<form>
元素包含了文件上传的整个表单,action
属性指定了处理文件上传的服务器端脚本,method
属性指定了表单提交的HTTP方法为 post
,enctype
属性设置为 multipart/form-data
以支持文件上传。<label>
元素用于显示文本标签,上述示例中label跟元素联动,提升用户体验。<input type="file">
是文件上传的核心元素,它创建了一个文件选择框。id
属性用于关联 <label>
元素,name
属性用于标识在提交表单时的字段名。<button>
元素用于提交表单。这只是一个基本的HTML结构,实际上,要使文件上传功能更加完善,还需要使用后端技术来处理文件的接收和存储。涉及后端的代码逻辑就不在这里陈述了。后续会专门编写后端接收文件上传的相关文章。
另外单文件上传还可以结合JavaScript语言来实现,以下是一个简单的例子,演示如何使用JavaScript结合HTML实现文件上传,并通过Ajax发送文件到服务器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript文件上传示例</title>
</head>
<body>
<input type="file" id="fileInput" />
<button onclick="uploadFile()">上传文件</button>
<progress id="progressBar" value="0" max="100"></progress>
<div id="status"></div>
<script>
function uploadFile() {
var fileInput = document.getElementById('fileInput');
var progressBar = document.getElementById('progressBar');
var status = document.getElementById('status');
var file = fileInput.files[0];
if (!file) {
status.innerHTML = '请选择文件';
return;
}
var formData = new FormData();
formData.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
var percent = (e.loaded / e.total) * 100;
progressBar.value = percent;
status.innerHTML = percent.toFixed(2) + '% 上传中...';
}
};
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
status.innerHTML = '上传完成';
} else if (xhr.readyState === 4 && xhr.status !== 200) {
status.innerHTML = '上传失败';
}
};
xhr.send(formData);
}
</script>
</body>
</html>
本人这里也提供一个基于Vue3的文件上传实现,代码如下
<template>
<el-dialog
class="upload-file-dialog"
title="文件上传"
width="600px"
height="300px"
>
<el-row class="file-info">
<el-col :span="12" class="file-info-name">
<span class="title">当前文件夹:</span><span class="content">{{folderObj.filename}}</span>
</el-col>
<el-col :span="12" class="file-info-update-time">
<span class="title">最后更新时间:</span><span class="content">{{folderObj.updateTime}}</span>
</el-col>
</el-row>
<el-row>
<el-col>
<el-upload
:auto-upload="false"
class="upload-demo"
drag
action="#"
multiple
:on-change="uploadContext.handleChange"
v-model:file-list="formData.fileList"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
拖动文件到这里或者<em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip">
文件大小不超过10MB
</div>
</template>
</el-upload>
</el-col>
</el-row>
<el-row class="btns">
<el-col>
<el-button type="primary" @click="uploadContext.upload">开始上传</el-button>
</el-col>
</el-row>
</el-dialog>
</template>
<script setup>
import { onMounted, reactive, getCurrentInstance } from 'vue'
import axios from 'axios'
const props = defineProps(['folderObj'])
const that = getCurrentInstance()
const ctx = that.ctx //当前实例的上下文
const formData = reactive({
fileList: [],
imgSrc: ''
})
const uploadContext = {
upload: ()=>{
formData.fileList.forEach((item, index)=>{
let formData = new FormData()
formData.append('fileId', item.uid)
formData.append('filename', item.name)
formData.append('file', item.raw)
formData.append('fileSize', item.size)
formData.append('fileSizeDesc', item.size + '')
formData.append('fileSuffix', item.name.substring(item.name.lastIndexOf(".")+1))
formData.append('identifier', item.raw.type)
axios.post('/pan/file/upload', formData)
.then(res=>{
console.log(res) //显示上传文件结果
})
})
},
/**
* 文件上传控件变化处理,这里可以增加进度条的显示处理逻辑,本人这里就处理这块代码逻辑了
*/
handleChange: (uploadFile, uploadFileList)=>{
console.log(formData.fileList)
}
}
</script>
<style lang="scss">
.upload-file-dialog {
.el-dialog__body{
padding: 10px 15px;
}
.file-info{
padding: 0 0 5px 0;
.file-info-update-time{
text-align: right;
}
}
.btns{
.el-col{
text-align: right;
}
}
}
</style>