vue 上传文件到 OSS

在 Vue 项目中实现不经过后端服务器直接上传文件到阿里云 OSS,可通过以下几种方案实现。以下是综合各来源的最佳实践和注意事项:


方案一:使用 OSS SDK 直传(前端配置密钥,不推荐)

  1. 安装依赖
shell 复制代码
npm install ali-oss --save
  1. 封装上传方法
    utils/oss.js 中创建客户端实例并封装上传逻辑:
js 复制代码
import OSS from 'ali-oss';
const client = new OSS({
  region: 'oss-cn-hangzhou', // 替换为你的区域
  accessKeyId: 'your-access-key-id', // 阿里云 AccessKeyId
  accessKeySecret: 'your-access-key-secret', // 阿里云 AccessKeySecret
  bucket: 'your-bucket-name' // OSS 存储桶名称
});
export async function uploadFile(file) {
  try {
    const fileName = `uploads/${file.name}`; // 自定义文件路径
    const result = await client.put(fileName, file);
    return result.url; // 返回文件访问地址
  } catch (error) {
    console.error('上传失败:', error);
    throw error;
  }
}
  1. Vue 组件调用
html 复制代码
<template>
  <input type="file" @change="handleUpload" />
</template>
<script>
import { uploadFile } from '@/utils/oss.js';
export default {
  methods: {
    async handleUpload(event) {
      const file = event.target.files[0];
      const url = await uploadFile(file);
      console.log('文件地址:', url);
    }
  }
};
</script>

注意:此方案需在前端暴露密钥,存在安全风险,仅适用于测试环境。


方案二:STS 临时凭证(推荐生产环境)

  1. 后端提供 STS 接口
    后端通过阿里云 STS 服务生成临时访问凭证(AccessKeyIdAccessKeySecretSecurityToken),并返回给前端。
  2. 前端动态获取凭证并上传
js 复制代码
import OSS from 'ali-oss';
import axios from 'axios';
async function uploadWithSTS(file) {
  // 1. 请求后端获取临时凭证
  const { data } = await axios.get('/api/sts-token');
  
  // 2. 使用临时凭证初始化 OSS 客户端
  const client = new OSS({
    region: data.region,
    accessKeyId: data.accessKeyId,
    accessKeySecret: data.accessKeySecret,
    stsToken: data.securityToken,
    bucket: data.bucketName
  });
  // 3. 上传文件
  const result = await client.put(`uploads/${file.name}`, file);
  return result.url;
}

优势:避免密钥暴露,凭证有效期可控。


方案三:服务端签名后直传

  1. 后端生成签名策略
    后端根据 OSS 要求生成 policysignature,返回给前端。
  2. 前端通过表单提交
js 复制代码
async function uploadWithSignature(file) {
  const { data } = await axios.get('/api/oss-signature'); // 获取签名信息
  const formData = new FormData();
  formData.append('key', `uploads/${file.name}`);
  formData.append('policy', data.policy);
  formData.append('OSSAccessKeyId', data.accessId);
  formData.append('signature', data.signature);
  formData.append('file', file);
  const res = await axios.post(data.host, formData, {
    headers: { 'Content-Type': 'multipart/form-data' }
  });
  return `${data.host}/${formData.get('key')}`; // 返回文件地址
}

适用场景:无需 SDK,兼容性强。


关键注意事项

  1. 跨域配置
    在阿里云 OSS 控制台配置跨域规则,允许 POSTPUT 方法,并设置允许来源(如 * 或具体域名)。
  2. 文件命名
    避免文件名冲突,建议使用唯一标识(如 UUID + 时间戳):
js 复制代码
const fileName = `${Date.now()}-${Math.random().toString(36).substring(2)}.${file.name.split('.').pop()}`;
  1. 大文件分片上传
    使用 multipartUpload 方法处理大文件,支持进度回调:
js 复制代码
const result = await client.multipartUpload(fileName, file, {
  progress: (p) => console.log(`上传进度: ${(p * 100).toFixed(2)}%`)
});
  1. 取消上传
    通过 client.cancel() 中断上传任务。

方案对比

方案 安全性 适用场景 依赖
SDK 直传 低(密钥暴露) 测试环境 ali-oss
STS 临时凭证 生产环境 ali-oss + 后端接口
服务端签名直传 兼容旧项目 无 SDK

完整示例(STS 方案)

html 复制代码
<template>
  <el-upload
    action="#"
    :http-request="customUpload"
    :show-file-list="false"
  >
    <el-button>选择文件</el-button>
  </el-upload>
</template>
<script>
import OSS from 'ali-oss';
import axios from 'axios';
export default {
  methods: {
    async customUpload({ file }) {
      try {
        // 异步获取临时凭证
        const { data } = await axios.get('/api/sts-token');
        
        // 初始化 OSS 客户端
        const client = new OSS({
          region: data.region,
          accessKeyId: data.accessKeyId,
          accessKeySecret: data.accessKeySecret,
          stsToken: data.securityToken,
          bucket: data.bucketName
        });
        // 上传并获取地址
        const result = await client.put(`uploads/${file.name}`, file);
        this.$message.success(`上传成功: ${result.url}`);
      } catch (error) {
        this.$message.error('上传失败');
      }
    }
  }
};
</script>

根据安全需求选择方案:生产环境优先使用 STS 临时凭证服务端签名,测试环境可简化为 SDK 直传。更多细节可参考阿里云官方文档或各来源的完整代码。

相关推荐
恋猫de小郭4 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅10 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606111 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅11 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅12 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅12 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment12 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅12 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊12 小时前
jwt介绍
前端