You need to enable JavaScript to run this app. Expo React Native中Node.js接入Heroku react-simple-file-upload实现方法
优惠活动
大模型
产品
解决方案
定价
更多

Expo React Native中Node.js接入Heroku react-simple-file-upload实现方法

Heroku环境下适配react-simple-file-upload的持久存储落地实现

前期方案选型

因为Heroku dyno自带的临时文件系统会在部署、扩容、休眠重启时清空所有本地写入文件,完全无法满足上传文件的持久留存需求,因此优先选型Heroku Elements市场内、提供S3兼容访问接口的托管对象存储附加组件。这类方案不需要改造原有“文件上传后将公开访问链接存入业务数据库”的业务逻辑,也能完美适配react-simple-file-upload的上传链路,无额外兼容成本。

第一步:挂载Heroku侧存储组件

  • 在Heroku对应项目的附加组件面板,选择支持S3兼容接口的托管对象存储服务完成安装
  • 安装完成后,系统会自动在项目的环境变量(Config Vars)中注入存储访问密钥、存储桶名称、服务端点、公开访问域名等配置项,所有密钥类配置直接从环境变量读取即可,禁止硬编码到业务代码中

第二步:改造Node.js后端的上传逻辑(替换原有multer本地存储)

原有基于multer的本地存储逻辑因为依托Heroku临时文件系统无法正常工作,需要将multer的存储引擎替换为对接S3兼容存储的实现,最小化对原有业务代码的改动:

  1. 安装依赖:执行npm install multer-s3 aws-sdk完成对应存储引擎和SDK的安装
  2. 对比改造前后的multer配置:

    原失效的本地存储配置(仅适合本地开发环境):

    const multer = require('multer')
    // 原有逻辑:将文件写入本地uploads目录
    const upload = multer({
      storage: multer.diskStorage({
        destination: './uploads',
        filename: (req, file, cb) => cb(null, `${Date.now()}-${file.originalname}`)
      })
    })
    

    适配持久存储的配置:

    const multer = require('multer')
    const S3 = require('aws-sdk/clients/s3')
    const multerS3 = require('multer-s3')
    // 从Heroku环境变量读取存储配置
    const s3Client = new S3({
      endpoint: process.env.STORAGE_SERVICE_ENDPOINT,
      accessKeyId: process.env.STORAGE_ACCESS_KEY,
      secretAccessKey: process.env.STORAGE_SECRET_KEY,
      s3ForcePathStyle: true
    })
    // 改造后的存储逻辑:将文件直接写入托管存储桶
    const upload = multer({
      storage: multerS3({
        s3: s3Client,
        bucket: process.env.STORAGE_BUCKET_NAME,
        acl: 'public-read',
        key: (req, file, cb) => cb(null, `app-uploads/${Date.now()}-${file.originalname}`)
      })
    })
    
  3. 原有业务入库逻辑无需调整:multer-s3在文件上传完成后,会自动在接口返回值中生成文件的完整公开访问链接,直接按照原有逻辑将链接存入Heroku上的业务数据库即可。

第三步:对接Expo端react-simple-file-upload的直传逻辑

为了避免上传文件经过Node服务器中转消耗Heroku dyno的请求时长配额,可结合临时签名接口实现前端直传:

  • 在Node后端新增临时签名生成接口:使用存储的访问密钥,为指定文件路径、指定权限生成有时效的临时上传签名,接口的用户校验逻辑和原有业务权限体系保持一致
  • Expo端初始化react-simple-file-upload组件时,将上述签名接口的地址配置为组件的上传入口地址,组件会自动引导用户选择文件后,直传到托管存储桶
  • 直传完成后,前端拿到存储返回的文件公开链接,直接调用原有业务的链接保存接口完成数据库写入即可

落地避坑提醒

  • 绝对不要尝试在Heroku本地目录持久化上传文件:dyno的本地存储不具备跨实例、跨重启的持久能力,写入的文件会在任意实例变更时丢失
  • 配置存储桶的跨域访问规则时,要将Expo开发调试的本地地址、生产发布的线上域名加入允许列表,避免前端直传时被跨域策略拦截
  • 所有存储访问密钥、签名生成逻辑必须放在Node后端实现,禁止将密钥打包到前端Expo应用中,避免出现存储资源被盗用的风险

内容的提问来源于stack exchange,提问作者Fatma Mahmoud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 15:45:07