如何用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
相关产品推荐
相关产品推荐

