🗒️

React Native + AWS SDK v3 S3 上传踩坑实录

2025-12-044 分钟1,628

目录

type
Post
status
Published
date
Dec 4, 2025
slug
summary
tags
category
icon
password
在 React Native (Expo/CLI) 中使用 @aws-sdk/client-s3@aws-sdk/lib-storage 上传图片时,看似简单的逻辑却隐藏了多个环境兼容性深坑。本文记录了从报错到完美运行的全过程。

🛠️ 技术栈

  • Framework: React Native / Expo
  • SDK: AWS SDK for JavaScript v3 (@aws-sdk/client-s3, @aws-sdk/lib-storage)
  • Key Feature: Multipart Upload (多部分上传)

🛑 遇到的主要报错 (The Pits)

1. 格式不支持 (Body Data Error)

报错信息:
[Error: Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;.]
原因分析: 虽然 AWS SDK 文档说支持 Blob,但在 React Native 的 Hermes 引擎或特定环境下,直接将 fetch(uri).blob() 传给 SDK 经常失败。RN 的 Blob 实现与 Node.js 或标准 Web 环境存在差异。
解决方案: 必须将 Blob 转换为 Uint8Array。这是 AWS SDK 在所有环境下兼容性最好的二进制格式。

2. 环境缺失 (Prototype undefined)

报错信息:
[TypeError: Cannot read property 'prototype' of undefined] 或 Buffer is not defined
原因分析: AWS SDK v3 深度依赖 Node.js 的核心模块(主要是 bufferstream)。React Native 运行在 JSC/Hermes 环境中,默认没有这些全局变量。
解决方案: 安装 polyfill 库并在入口处强制注入 global.Buffer

3. 方法缺失 (blob.arrayBuffer is undefined)

报错信息:
[TypeError: blob.arrayBuffer is not a function]
原因分析: 较新的 Web 标准中 Blob 有 .arrayBuffer() 方法,但 RN 的 Blob 实现(尤其是旧版本或某些 Expo 版本)尚未完全支持此方法。
解决方案: 使用经典的 FileReader API 将 Blob 读取为 ArrayBuffer

4. 动态导入失败 (Unknown module)

报错信息:
[Error: Requiring unknown module "xxxx".]
原因分析: 为了节省性能尝试在函数内部使用 await import(...) 动态加载 SDK,但这会导致 Metro 打包器在解析依赖图时出错,或者缓存更新不及时。
解决方案: 老老实实使用顶层 静态导入 (Static Import)

✅ 最终解决方案

Step 1: 安装依赖

除了 AWS SDK,还需要安装必要的 Polyfill 库。

Step 2: 完整代码实现 (Hooks 封装)


💡 避坑总结 (Checklist)

  1. Polyfills 是必须的:不要抱侥幸心理,buffer, url-polyfill, get-random-values 这三剑客必须装。
  1. Uint8Array 是万金油:不要直接传 Blob 给 SDK 的 Body,React Native 处理不好。始终使用 fetch -> blob -> FileReader -> ArrayBuffer -> Uint8Array 的链路。
  1. 不要使用动态导入:RN Metro 对 await import() 支持不稳定,使用顶层 import 并重启 Metro (npm start -- --reset-cache)。
  1. 全局 Buffer 注入:确保代码执行前 global.Buffer 已经被赋值,通常放在入口文件或工具文件的最顶部。
提示:如果修改了 Polyfill 配置后仍然报错,记得清除 Metro 缓存重启! npx expo start -c 或 npm start -- --reset-cache
 

冷苏

全栈开发者 · 前端 / 移动端 / Python / 桌面应用

GitHub ⟶

1.6k

字数

4

分钟