You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js 13 API路由中使用Cloudflare R2存储桶?

在Next.js 13 API路由中向Cloudflare R2存储桶上传文件

前置准备

  1. 安装依赖:R2兼容AWS S3 API,直接使用官方AWS SDK即可
npm install @aws-sdk/client-s3
  1. 配置环境变量:在项目根目录创建.env.local文件,填入你的R2凭证信息
R2_ACCOUNT_ID=你的R2账户ID
R2_ACCESS_KEY_ID=你的R2访问密钥ID
R2_SECRET_ACCESS_KEY=你的R2秘密访问密钥
R2_BUCKET_NAME=目标R2存储桶名称

编写App Router API路由(Next.js 13+)

在app/api/upload/route.ts文件中编写上传逻辑:

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { NextResponse } from "next/server";

// 初始化兼容R2的S3客户端
const s3Client = new S3Client({
  region: "auto",
  endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID!,
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
  },
});

export async function POST(request: Request) {
  try {
    const formData = await request.formData();
    const file = formData.get("file") as File;

    if (!file) {
      return NextResponse.json({ error: "请选择要上传的文件" }, { status: 400 });
    }

    // 将File对象转换为Buffer
    const arrayBuffer = await file.arrayBuffer();
    const fileBuffer = Buffer.from(arrayBuffer);

    // 构造上传命令(添加时间戳避免文件名冲突)
    const uploadCommand = new PutObjectCommand({
      Bucket: process.env.R2_BUCKET_NAME,
      Key: `${Date.now()}-${file.name}`,
      Body: fileBuffer,
      ContentType: file.type,
    });

    await s3Client.send(uploadCommand);

    return NextResponse.json({
      message: "文件上传成功",
      fileName: `${Date.now()}-${file.name}`
    }, { status: 200 });
  } catch (error) {
    console.error("上传失败详情:", error);
    return NextResponse.json({ error: "文件上传失败,请重试" }, { status: 500 });
  }
}

前端调用示例

在组件中通过fetch调用API上传文件:

async function handleFileUpload(e) {
  const file = e.target.files[0];
  if (!file) return;

  const formData = new FormData();
  formData.append("file", file);

  const response = await fetch("/api/upload", {
    method: "POST",
    body: formData,
  });

  const result = await response.json();
  alert(result.message);
}

注意事项

  • 确保你的R2访问密钥拥有PutObject权限,避免权限不足错误
  • 若使用Pages Router,API路由写法类似,需在pages/api/upload.ts中导出处理函数,可参考官方FormData处理方式
  • 可根据需求自定义文件名规则,比如添加用户ID、哈希值等进一步避免冲突

内容的提问来源于stack exchange,提问作者Mohammed Bekele

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:01:21