单文件上传

2024-01-07 09:02:11 浏览数 (2)

随着Web应用的普及,文件上传功能成为许多网站和应用不可或缺的一部分。本文整理了个人学习过程中的笔记,为开发者提供全面的了解和实践经验。

单文件上传

在早期的html应用中,都是使用form标签中嵌套来实现文件上传的,具体代码如下

代码语言:javascript复制
<!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方法为 postenctype 属性设置为 multipart/form-data 以支持文件上传。
  • <label> 元素用于显示文本标签,上述示例中label跟元素联动,提升用户体验。
  • <input type="file"> 是文件上传的核心元素,它创建了一个文件选择框。id 属性用于关联 <label> 元素,name 属性用于标识在提交表单时的字段名。
  • <button> 元素用于提交表单。

这只是一个基本的HTML结构,实际上,要使文件上传功能更加完善,还需要使用后端技术来处理文件的接收和存储。涉及后端的代码逻辑就不在这里陈述了。后续会专门编写后端接收文件上传的相关文章。

另外单文件上传还可以结合JavaScript语言来实现,以下是一个简单的例子,演示如何使用JavaScript结合HTML实现文件上传,并通过Ajax发送文件到服务器

代码语言:javascript复制
<!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的文件上传实现,代码如下

代码语言:javascript复制
<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>

0 人点赞