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

如何用AWS SDK v3或Backblaze原生API生成客户端上传预签名URL?

解决Backblaze存储桶预签名URL/文件上传问题

一、AWS SDK v3 正确配置方案

你之前的代码未正确配置Backblaze的S3兼容端点和凭证,导致生成的URL指向AWS域名。修正后的代码如下:

import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import axios from "axios";

const region = process.env.BUCKET_REGION;
const bucket = process.env.BUCKET_NAME;
// Backblaze的Application Key ID对应AWS的accessKeyId,Application Key对应secretAccessKey
const credentials = {
  accessKeyId: process.env.APPLICATION_KEY_ID!,
  secretAccessKey: process.env.APPLICATION_KEY!,
};

// 配置S3客户端指向Backblaze的S3兼容端点
const client = new S3Client({
  region,
  credentials,
  endpoint: `https://s3.${region}.backblazeb2.com`,
  // 若你的存储桶不支持子域名格式(比如包含特殊字符),需开启forcePathStyle
  // forcePathStyle: true,
});

const expiresIn = 7 * 24 * 60 * 60; // 7天有效期
const filename = "test-file.txt"; // 替换为你的文件名
const command = new PutObjectCommand({ Bucket: bucket, Key: filename });
const signedUrl = await getSignedUrl(client, command, { expiresIn });

// 测试上传
await axios.put(signedUrl, "hello", {
  headers: {
    "Content-Type": "text/plain",
  },
});

关键修正点:

  • 添加credentials配置:用Backblaze的Application Key ID和Application Key填充
  • 显式设置endpoint为Backblaze的S3兼容地址,格式为https://s3.${region}.backblazeb2.com
  • AWS SDK v3默认使用v4签名,无需额外配置(Backblaze S3兼容仅支持v4签名)
  • 若存储桶名称包含.或其他特殊字符,需开启forcePathStyle: true,此时URL会变为https://s3.us-east-005.backblazeb2.com/<BUCKET_NAME>/<KEY>格式

二、Backblaze原生API 405错误修复

你遇到的405错误是因为误用了PUT请求,Backblaze原生上传API要求使用POST请求,且需正确设置请求头。修正后的代码:

import B2 from "backblaze-b2";
import axios from "axios";

const b2 = new B2({
  applicationKey: process.env.APPLICATION_KEY!,
  applicationKeyId: process.env.APPLICATION_KEY_ID!,
});
await b2.authorize();

const bucketName = process.env.BUCKET_NAME!;
const bucketApi = await b2.getBucket({ bucketName });
const bucket = bucketApi.data.buckets.find(
  (b) => b.bucketName === bucketName
);

const signedUrlApi = await b2.getUploadUrl({ bucketId: bucket.bucketId });
const fileContent = "testing123";
const contentLength = Buffer.byteLength(fileContent);

// 使用POST请求上传
await axios.post(signedUrlApi.data.uploadUrl, fileContent, {
  headers: {
    Authorization: signedUrlApi.data.authorizationToken,
    "Content-Type": "text/plain", // 根据文件类型设置
    "Content-Length": contentLength.toString(),
  },
});

关键修正点:

  • 将axios.put改为axios.post:Backblaze原生上传接口仅接受POST请求
  • 添加Content-Length头:必须设置为文件内容的字节长度
  • 确保Content-Type与上传文件类型匹配,若不确定可设为b2/x-auto(Backblaze会自动识别)

内容的提问来源于stack exchange,提问作者55 Cancri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:17:41