当前位置: 首页 > backend >正文

upload文件上传

<template><div class="upload-container"><!-- 文件选择 --><inputtype="file"accept="video/*"@change="handleFileChange"ref="fileInput"/><!-- 上传按钮 --><button@click="startUpload":disabled="!file || isUploading">{{ isUploading ? `上传中... ${progress}%` : '上传视频' }}</button><!-- 进度条 --><div v-if="isUploading" class="progress-bar"><div class="progress" :style="{ width: progress + '%' }"></div></div><!-- 错误提示 --><div v-if="error" class="error">{{ error }}</div><!-- 视频预览 --><videov-if="previewUrl":src="previewUrl"controlsclass="preview"></video></div>
</template>
<script>
import axios from 'axios';
export default {name: 'Upload',data() {return {file: undefined,previewUrl: undefined,isUploading:false,progress: 0,error: undefined}},methods: {handleFileChange(e) {const selectedFile = e.target.files[0];if (!selectedFile) return;// 验证文件类型if (!selectedFile.type.startsWith('video/')) {this.error = '请选择视频文件!';return;}// 验证文件大小(例如限制100MB)const MAX_SIZE = 100 * 1024 * 1024; // 100MBif (selectedFile.size > MAX_SIZE) {this.error = '文件大小不能超过100MB!';return;}this.file = selectedFile;this.previewUrl = URL.createObjectURL(selectedFile);this.error = ''; // 清除之前的错误},async startUpload() {if (!this.file) return;this.isUploading = true;this.progress = 0;this.error = '';const formData = new FormData();formData.append('file', this.file); // 字段名需与后端一致try {const response = await axios.post('http://192.168.8.172:8077/common/upload',formData,{headers: {'Content-Type': 'multipart/form-data', // 必须设置'token': localStorage.getItem("usertoken")},onUploadProgress: (progressEvent) => {// 计算上传进度this.progress = Math.round((progressEvent.loaded / progressEvent.total) * 100);},timeout: 300000, // 5分钟超时});console.log('上传成功:', response.data);alert('视频上传成功!');} catch (err) {this.handleUploadError(err);} finally {this.isUploading = false;}},// 错误处理handleUploadError(err) {if (err.code === 'ECONNABORTED') {this.error = '上传超时,请检查网络或稍后重试';} else if (err.response) {// 后端返回的错误this.error = err.response.data.message || `上传失败: ${err.response.status}`;} else {this.error = '上传失败,请检查网络连接';}console.error('上传错误:', err);}}}
</script>
<style scoped>
.upload-container {max-width: 500px;margin: 0 auto;padding: 20px;font-family: Arial, sans-serif;
}input[type="file"] {margin-bottom: 15px;display: block;
}button {background-color: #4CAF50;color: white;padding: 10px 15px;border: none;border-radius: 4px;cursor: pointer;font-size: 16px;
}button:disabled {background-color: #cccccc;cursor: not-allowed;
}.progress-bar {width: 100%;height: 10px;background-color: #f1f1f1;margin: 15px 0;border-radius: 5px;overflow: hidden;
}.progress {height: 100%;background-color: #4CAF50;transition: width 0.3s;
}.error {color: #ff0000;margin-top: 10px;
}.preview {width: 100%;max-height: 300px;margin-top: 20px;border: 1px solid #ddd;border-radius: 4px;
}
</style>

以上为vue2代码

<template><div class="upload-container"><!-- 文件选择 --><inputtype="file"accept="video/*"@change="handleFileChange"ref="fileInput"/><!-- 上传按钮 --><button@click="startUpload":disabled="!file || isUploading">{{ isUploading ? `上传中... ${progress}%` : '上传视频' }}</button><!-- 进度条 --><div v-if="isUploading" class="progress-bar"><div class="progress" :style="{ width: progress + '%' }"></div></div><!-- 错误提示 --><div v-if="error" class="error">{{ error }}</div><!-- 视频预览 --><videov-if="previewUrl":src="previewUrl"controlsclass="preview"></video></div></template><script setup>import { ref } from 'vue';import axios from 'axios';const fileInput = ref(null);const file = ref(null);const previewUrl = ref('');const isUploading = ref(false);const progress = ref(0);const error = ref('');// 选择文件const handleFileChange = (e) => {const selectedFile = e.target.files[0];if (!selectedFile) return;// 验证文件类型if (!selectedFile.type.startsWith('video/')) {error.value = '请选择视频文件!';return;}// 验证文件大小(例如限制100MB)const MAX_SIZE = 100 * 1024 * 1024; // 100MBif (selectedFile.size > MAX_SIZE) {error.value = '文件大小不能超过100MB!';return;}file.value = selectedFile;previewUrl.value = URL.createObjectURL(selectedFile);error.value = ''; // 清除之前的错误};// 开始上传const startUpload = async () => {if (!file.value) return;isUploading.value = true;progress.value = 0;error.value = '';const formData = new FormData();formData.append('file', file.value); // 字段名需与后端一致try {const response = await axios.post('http://localhost:8077/common/upload',formData,{headers: {'Content-Type': 'multipart/form-data', // 必须设置},onUploadProgress: (progressEvent) => {// 计算上传进度progress.value = Math.round((progressEvent.loaded / progressEvent.total) * 100);},timeout: 300000, // 5分钟超时});console.log('上传成功:', response.data);alert('视频上传成功!');} catch (err) {handleUploadError(err);} finally {isUploading.value = false;}};// 错误处理const handleUploadError = (err) => {if (err.code === 'ECONNABORTED') {error.value = '上传超时,请检查网络或稍后重试';} else if (err.response) {// 后端返回的错误error.value = err.response.data.message || `上传失败: ${err.response.status}`;} else {error.value = '上传失败,请检查网络连接';}console.error('上传错误:', err);};</script><style scoped>.upload-container {max-width: 500px;margin: 0 auto;padding: 20px;font-family: Arial, sans-serif;}input[type="file"] {margin-bottom: 15px;display: block;}button {background-color: #4CAF50;color: white;padding: 10px 15px;border: none;border-radius: 4px;cursor: pointer;font-size: 16px;}button:disabled {background-color: #cccccc;cursor: not-allowed;}.progress-bar {width: 100%;height: 10px;background-color: #f1f1f1;margin: 15px 0;border-radius: 5px;overflow: hidden;}.progress {height: 100%;background-color: #4CAF50;transition: width 0.3s;}.error {color: #ff0000;margin-top: 10px;}.preview {width: 100%;max-height: 300px;margin-top: 20px;border: 1px solid #ddd;border-radius: 4px;}</style>

以上为vue3代码

http://www.xdnf.cn/news/5094.html

相关文章:

  • ES6新增Set、Map两种数据结构、WeakMap、WeakSet举例说明详细。(含DeepSeek讲解)
  • 【PINN】DeepXDE学习训练营(18)——operator-diff_rec_unaligned_pideeponet.py
  • 安全核查基线-1.LPD服务
  • 【软件设计师:体系结构】15.计算机体系结构概论
  • 将/root下的employee.json挪到/home/Downloads/
  • 让模型具备“道生一,一生二,二生三,三生万物”的现实实用主义能力
  • Stagehand:AI驱动的下一代浏览器自动化框架
  • 历史温度曲线能优化样本存储的条件还是确保样本处于稳定状态呢?
  • Linux系统入门第十一章 --Shell编程之函数与数组
  • CreArt 2.5.6 |无限AI图片生成工具,将文字描述转化为独特艺术作品,解锁高级版
  • FastChat部署大模型
  • 从量子计算到人工智能代理
  • PPT插入图像自带透明
  • 分布式处理架构
  • android动态调试
  • Android对工程中的String中文字符的整理
  • 多序列比对软件 Clustal Omega 介绍
  • 深度学习 ———— 迁移学习
  • 动态路由匹配
  • 家庭NAS怎么选?
  • 软考高级系统架构设计师备考分享:操作系统核心知识点整理
  • QML AnimatedImage组件详解
  • SAP note 3565626 : Baltimore CyberTrust 根证书即将过期
  • AGV通信第3期|AGV集群智能应急响应系统:从故障感知到快速恢复
  • 微信小程序地图缩放scale隐性bug
  • 记忆化搜索
  • workbench fluent动画
  • 2025年现代职业教育质量提升计划(植保无人机实训室)解决方案
  • 【基础】模型上下文协议(Model Context Protocol, MCP)根本原理与工作机制详解
  • “点对点通信(Point-to-Point)”和“端对端通信(End-to-End)”