React + Node.js + 阿里云OSS 文件上传系统实战指南

123 阅读3分钟

📖 前言

在Web开发中,文件上传是一个常见的需求。本文将带你使用React + TypeScript + Node.js + 阿里云OSS构建一个企业级的文件上传系统。通过本教程,你将掌握阿里云OSS的配置、前端文件上传组件的开发、后端API的实现等核心技能。

�� 第一步:阿里云OSS配置

1. 登录阿里云控制台

访问 阿里云控制台,使用你的阿里云账号登录。

2. 进入RAM访问控制

在控制台搜索"RAM",点击"RAM访问控制"进入用户管理页面。

3. 创建用户

  • 点击"创建用户"
  • 选择"编程访问"(获取AccessKey)
  • 填写用户名,如:oss-upload-user

4. 创建AccessKey

  • 创建完成后,点击"创建AccessKey"
  • 选择"继续使用AccessKey"
  • 保存AccessKey ID和AccessKey Secret(重要!请妥善保管)

5. 配置权限

  • 在用户详情页,点击"添加权限"
  • 搜索"OSS"并选择"AliyunOSSFullAccess"
  • 点击"确定"完成权限配置

6. 创建OSS Bucket

  • 在控制台搜索"OSS",进入对象存储服务
  • 点击"创建Bucket"
  • 选择区域(如:华东1-上海)
  • 设置Bucket名称,如:my-upload-bucket
  • 其他选项保持默认,点击"确定"

环境变量配置

OSS_REGION=oss-cn-shanghai
OSS_ACCESS_KEY_ID=你的AccessKeyId
OSS_ACCESS_KEY_SECRET=你的AccessKeySecret
OSS_BUCKET_NAME=你的Bucket名称

第二步:后端核心实现

文件验证中间件

const validateFile = async (ctx, next) => {
    const file = ctx.request.files?.file;
    
    if (!file) {
        ctx.body = { status: 'error', msg: '请选择文件' };
        return;
    }
    
    // 文件大小限制:10MB
    const maxSize = 10 * 1024 * 1024;
    if (file.size > maxSize) {
        ctx.body = { status: 'error', msg: '文件大小不能超过10MB' };
        return;
    }
    
    await next();
};

文件上传接口

router.post('/upload', validateFile, async (ctx) => {
    try {
        const { filepath, originalFilename } = ctx.request.files.file;
        
        // 生成唯一文件名,避免冲突
        const timestamp = Date.now();
        const uniqueFilename = `uploads/${timestamp}_${originalFilename}`;
        
        const result = await client.put(uniqueFilename, filepath);
        
        ctx.body = {
            url: result.url,
            status: 'done',
            name: uniqueFilename,
            uid: timestamp.toString()
        };
    } catch (error) {
        console.error('上传失败:', error);
        ctx.body = { status: 'error', msg: '上传失败,请重试' };
    }
});

  

�� 第三步:前端组件实现

核心上传逻辑

const customUpload = async (file: FileType) => {
    try {
        const formData = new FormData();
        formData.append('file', file);
        
        const response = await request.post('/upload', formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
        });
        
        const result = response.data;
        
        if (result.status === 'done') {
            // 上传成功处理
            const newFile = {
                ...file,
                status: 'done',
                response: { status: 'done', url: result.url }
            } as UploadFile;
            
            setFileList([newFile]);
            localStorage.setItem("myavatar", JSON.stringify([newFile]));
            onAvatarChange(result.url);
            message.success('头像上传成功!');
        } else {
            message.error(result.msg || '上传失败');
            return false;
        }
    } catch (error) {
        console.error('上传失败:', error);
        message.error('上传失败,请重试');
        return false;
    }
    
    return false; // 阻止默认上传
};

 // 文件列表变化调用
  const handleChange: UploadProps["onChange"] = ({ fileList: newFileList }) => {
    setFileList(newFileList);
  };

Ant Designhttps://ant-design.antgroup.com/index-cn

 组件

<>
      <ImgCrop rotationSlider>
        <Upload
          beforeUpload={customUpload}
          listType="picture-card"
          fileList={fileList}
          onPreview={handlePreview}
          onChange={handleChange}
          maxCount={1}
          accept="image/*"
        >
          {fileList.length >= 1 ? null : <img src={Avatar} alt="" />}
        </Upload>
      </ImgCrop>

      {/* 头像预览 */}
      {previewImage && (
        <Image
          wrapperStyle={{ display: "none" }}
          preview={{
            visible: previewOpen,
            onVisibleChange: (visible) => setPreviewOpen(visible),
            afterOpenChange: (visible) => !visible && setPreviewImage(""),
          }}
          src={previewImage}
        />
      )}
    </>

🚀 核心特性

  1. 智能文件验证 - 文件大小、类型检查
  2. 图片裁剪功能 - 集成antd-img-crop
  3. 本地缓存优化 - 头像信息本地存储
  4. 错误处理完善 - 友好的用户提示

💡 技术亮点

  • 防重复刷新 - 使用Promise缓存避免重复请求
  • 文件命名优化 - 时间戳+原文件名避免冲突
  • 用户体验优化 - 实时预览、进度提示

🔒 安全考虑

  1. 环境变量配置 - 敏感信息不硬编码
  2. 文件大小限制 - 防止恶意大文件上传
  3. 权限最小化 - OSS权限精确控制

本期内容就到这里,主页有火柴能点着的干货!!,“真的嘛博主?” 那我就收藏+关注了