为何AWS PutObjectCommand结合SST无需显式处理即可完成文件上传?
关于SST预签名URL文件上传的疑问
我正在试用SST工具,它能通过代码配置AWS服务与全栈Web应用。在其API教程中,我编写了如下文件上传函数:
import { Resource } from "sst"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import { S3Client, GetObjectCommand, PutObjectCommand, ListObjectsV2Command, } from "@aws-sdk/client-s3"; const s3 = new S3Client({}); export async function upload() { const command = new PutObjectCommand({ Key: crypto.randomUUID(), Bucket: Resource.MyBucket.name, }); const body = await getSignedUrl(s3, command); return { statusCode: 200, body }; }
这个函数里完全没有显式处理文件的逻辑,我原本以为它只会在指定S3桶中创建一个空文件。但服务器启动后,我通过curl命令上传文件:
curl --upload-file somefile.txt "$(curl https://sometestapi.execute-api.eu-west-1.amazonaws.com)"
结果在AWS控制台查看S3桶时,却能看到somefile.txt及其完整内容。我搞不懂两个核心问题:
- a) API是如何获取到该文件的?函数里没有任何相关处理逻辑
- b) 文件又是如何传输至S3的?
打印command和body得到如下内容:
| +26ms { | +26ms command: PutObjectCommand { | +26ms middlewareStack: { | +26ms add: [Function: add], | +26ms addRelativeTo: [Function: addRelativeTo], | +26ms clone: [Function: clone], | +26ms use: [Function: use], | +26ms remove: [Function: remove], | +26ms removeByTag: [Function: removeByTag], | +26ms concat: [Function: concat], | +26ms applyToStack: [Function: cloneTo], | +26ms identify: [Function: identify], | +26ms identifyOnResolve: [Function: identifyOnResolve], | +26ms resolve: [Function: resolve] | +26ms }, | +26ms serialize: [AsyncFunction: se_PutObjectCommand], | +26ms deserialize: [AsyncFunction: de_PutObjectCommand], | +26ms input: { | +26ms Key: '860d1393-4232-48fc-4d4b-b42c0c8a6473', | +26ms Bucket: 'mytestprojectname-testbucket-tokfzzao' | +26ms } | +26ms } | +26ms } | +26ms { | +26ms body: 'https://mytestprojectname-testbucket-tokfzzao.s3.eu-west-1.amazonaws.com/860d1393-4232-48fc-9d4a-b42c0c8a6473?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=<removed-credentials>&X-Amz-Date=20240607T170451Z&X-Amz-Expires=900&X-Amz-Security-Token=<removed-security-token>&X-Amz-Signature=<removed-signature>&X-Amz-SignedHeaders=host&x-id=PutObject' | +26ms }
我调试了函数中所有可用变量,未发现任何包含上传文件的内容。原本以为没有显式处理逻辑的话,文件不会被上传至S3。
补充一点背景:客户端实现相同功能的流程逻辑清晰,先获取预签名URL,再将文件上传至该URL,代码如下:
const image = await fetch(url // pre-signed URL, { body: file // file from HTML form, method: "PUT", headers: { "Content-Type": file.type, "Content-Disposition": `attachment; filename="${file.name}"`, }, });
但上述服务器端示例中似乎完全缺失了最后一步,恳请解惑。
内容的提问来源于stack exchange,提问作者Josh Jahans
相关产品推荐
相关产品推荐

