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

vue3使用七牛云上传文件

以下是一个完整的 Vue 3 集成七牛云文件上传 的解决方案,包含环境搭建、代码实现和注意事项:

一、环境准备

  1. 安装七牛云 SDK

    bash

    npm install qiniu-js@3.4.2  # 推荐使用稳定版本
    
  2. 获取七牛云配置

    • 在七牛云控制台创建 存储空间,获取以下信息:
      • AccessKey 和 SecretKey(用于服务端生成上传凭证)
      • Bucket 名称 和 存储空间域名(如 your-bucket.qiniucdn.com

二、完整代码实现

组件文件:QiniuUpload.vue
<template><div class="qiniu-upload-container"><!-- 文件选择按钮 --><inputtype="file"ref="fileInput"@change="handleFileChange"accept="image/*,video/*,application/pdf" <!-- 支持多类型 -->style="display: none"/><button @click="triggerFileSelect">选择文件</button><!-- 上传按钮 --><button@click="handleUpload":disabled="!file || isUploading || !qiniuReady"class="upload-button">{{ isUploading ? '上传中...' : '开始上传' }}</button><!-- 上传进度 --><div v-if="isUploading" class="progress-bar">进度:{{ progress }}%</div><!-- 结果展示 --><div v-if="fileUrl" class="preview-container"><span>已上传:</span><a :href="fileUrl" target="_blank" rel="noopener">{{ fileName }}</a><!-- 图片预览 --><imgv-if="isImageFile":src="fileUrl"alt="预览"class="preview-image"/></div><!-- 错误提示 --><div v-if="error" class="error-message">{{ error }}</div></div>
</template><script setup>
import { ref, onMounted, watch } from 'vue';
import qiniu from 'qiniu-js'; // 导入七牛云 SDK// 响应式状态
const file = ref(null); // 选中的文件
const isUploading = ref(false);
const progress = ref(0);
const fileUrl = ref('');
const fileName = ref('');
const error = ref('');
const qiniuReady = ref(false); // SDK 就绪状态
const isImageFile = ref(false); // 是否为图片文件// 七牛云配置(需替换为你的实际信息)
const bucket = 'your-bucket-name'; // 存储空间名称
const domain = 'your-bucket.qiniucdn.com'; // 存储空间域名
const region = qiniu.region.z2; // 空间区域(根据实际区域修改,如 z0、z1、z2 等)// 初始化 SDK
onMounted(() => {// 验证 SDK 可用性if (qiniu && qiniu.upload) {qiniuReady.value = true;} else {error.value = '七牛云 SDK 加载失败,请检查依赖';}
});// 触发文件选择
const triggerFileSelect = () => {fileInput.value.click();
};// 文件选择处理
const fileInput = ref(null);
const handleFileChange = (e) => {const selectedFile = e.target.files?.[0];if (!selectedFile) return;file.value = selectedFile;fileName.value = selectedFile.name;isImageFile.value = selectedFile.type.startsWith('image/');error.value = ''; // 清除之前的错误
};// 上传文件
const handleUpload = async () => {if (!file.value || !qiniuReady.value || isUploading.value) return;try {isUploading.value = true;progress.value = 0;// 1. 获取上传凭证(需先实现服务端接口)const token = await fetchUploadToken();// 2. 创建上传配置const config = {useCdnDomain: true, // 使用 CDN 加速域名region, // 空间区域};// 3. 生成唯一文件名(避免重复)const key = generateUniqueFileName(file.value);// 4. 执行上传const observable = qiniu.upload(file.value, // 上传的文件对象key, // 自定义文件名(可选,不填则使用原始文件名)token, // 上传凭证{fname: file.value.name, // 原始文件名(可选)mimeType: file.value.type, // 文件 MIME 类型(可选)},config);// 5. 订阅上传进度和结果const subscription = observable.subscribe({next: (res) => {progress.value = Math.round(res.total.percent); // 更新进度},error: (err) => {isUploading.value = false;error.value = `上传失败:${err.message}`;console.error('上传错误:', err);},complete: (res) => {isUploading.value = false;fileUrl.value = `https://${domain}/${res.key}`; // 构建文件访问地址console.log('上传成功:', res);},});// 6. 清理订阅(组件卸载时)watch(() => isUploading.value, (newVal) => {if (!newVal && subscription) {subscription.unsubscribe();}});} catch (err) {isUploading.value = false;error.value = `操作失败:${err.message}`;}
};// 生成唯一文件名(时间戳+随机字符串)
const generateUniqueFileName = (file) => {const ext = file.name.split('.').pop();const timestamp = Date.now();const randomStr = Math.random().toString(36).substring(2, 10);return `${timestamp}_${randomStr}.${ext}`;
};// 获取上传凭证(需对接你的服务端接口)
const fetchUploadToken = async () => {try {const response = await fetch('/api/qiniu/get-token', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ bucket }), // 传递 Bucket 名称给服务端});if (!response.ok) throw new Error('获取凭证失败');const data = await response.json();if (!data.token) throw new Error('凭证无效');return data.token;} catch (err) {throw new Error(`获取凭证失败:${err.message}`);}
};
</script><style scoped>
.qiniu-upload-container {max-width: 600px;margin: 20px auto;padding: 20px;border: 1px solid #e5e7eb;border-radius: 8px;
}.upload-button {background-color: #3b82f6;color: white;padding: 8px 16px;border: none;border-radius: 4px;cursor: pointer;margin-left: 10px;
}.progress-bar {height: 4px;background-color: #e5e7eb;margin: 10px 0;border-radius: 2px;position: relative;
}.progress-bar::before {content: '';height: 100%;width: ${(props) => props.progress}%;background-color: #3b82f6;border-radius: 2px;transition: width 0.3s ease;
}.preview-container {margin-top: 20px;padding: 15px;border: 1px dashed #e5e7eb;border-radius: 4px;
}.preview-image {max-width: 300px;max-height: 200px;margin-top: 10px;display: block;
}.error-message {color: #dc2626;margin-top: 10px;
}
</style>

三、关键配置说明

  1. 空间区域(Region)配置
    七牛云不同区域对应不同的 region 值,需根据你的存储空间所在地选择:

    • 华东区域(z0):qiniu.region.z0
    • 华北区域(z1):qiniu.region.z1
    • 华南区域(z2):qiniu.region.z2
    • 北美区域(na0):qiniu.region.na0
    • 东南亚区域(as0):qiniu.region.as0
  2. 文件类型限制
    通过 accept 属性限制允许上传的文件类型:

    html

    预览

    accept="image/*,video/*,application/pdf" <!-- 允许图片、视频、PDF -->
    
  3. 安全注意事项

    • 永远不要在前端暴露 AccessKey/SecretKey,必须通过服务端生成上传凭证。
    • 对上传的文件进行大小限制(前端和服务端双重校验):

      javascript

      // 前端校验(示例:限制 50MB)
      const maxFileSize = 50 * 1024 * 1024; // 50MB
      if (file.value.size > maxFileSize) {error.value = '文件大小不能超过 50MB';file.value = null;return;
      }
      

四、常见问题解决

  1. 上传凭证失效

    • 确保服务端接口返回的 Token 未过期(默认有效期 3600 秒)。
    • 检查 Bucket 名称是否正确。
  2. 跨域问题

    • 若文件访问地址出现跨域,需在七牛云控制台配置 CORS 规则
  3. SDK 加载失败

    • 确认 qiniu-js 已正确安装,且导入路径无误:

      javascript

      import qiniu from 'qiniu-js'; // 确保包名正确
      

  4. 进度条不更新

    • 确保订阅了 next 事件,并正确更新 progress 状态。

五、效果演示

  1. 选择文件后点击上传,显示实时进度。
  2. 上传成功后显示文件链接和预览(图片文件)。
  3. 错误场景(如文件过大、凭证失效)显示友好提示。

通过以上方案,可实现安全、高效的 Vue 3 七牛云文件上传功能。如有具体问题,请提供错误日志或配置细节,以便进一步排查!

相关文章:

  • MySQL主从同步原理
  • 快速失败(fail-fast)和安全失败(fail-safe)的区别
  • 传统医疗系统文档集中标准化存储和AI智能化更新路径分析
  • 爬虫知识之IP代理
  • 用 AI 让学习更懂你:如何打造自动化个性化学习系统?
  • 嵌入式开发方向开发利器
  • OpenLayers 加载全屏显示控件
  • 【萤火工场GD32VW553-IOT开发板】ADC电压的LabVIEW采集
  • 【Code Agent Benchmark】论文分享No.15:TAU-Bench
  • 标准版v5.6.1, 优化了一些细节提升体验
  • RabbitMQ的详细使用
  • 超详细网络介绍(超全)
  • 5.24本日总结
  • CQF预备知识:Python相关库 -- NumPy 基础知识 - 数组创建
  • Ubuntu20.04 gr-gsm完整安装教程
  • SQL每日一题
  • SQL SERVER常用聚合函数整理及示例
  • 全面指南:使用Node.js和Python连接与操作MongoDB
  • 二十五、面向对象底层逻辑-SpringMVC九大组件之HandlerMapping接口设计
  • 【Linux】进程基本概念与基本操作
  • 网站控制面板中设置目录权限/成人本科
  • 武山县建设局网站/常州网站推广
  • 好看的 网站后台模板/千锋教育地址
  • 广州制作网站哪家专业/六年级上册数学优化设计答案
  • 大连 祥云 网站优化/关键词优化的主要工具
  • 用php做网站需要什么/有产品怎么找销售渠道