Angular15中@aws-sdk/client-s3的CopyObjectCommand无法复制文件
问题:S3 CopyObjectCommand返回成功但未完成文件复制
在Angular 15项目中使用@aws-sdk/client-s3@3.312.0,PutObjectCommand可以正常存储文件,但调用CopyObjectCommand返回成功响应后,目标存储桶中并未出现复制后的文件。实际需求是重命名文件,因此会在复制后调用DeleteObjectCommand。
传入的复制参数如下:
Bucket: "simplify-pilot-media-dev" CopySource: "/simplify-pilot-media-dev/profiles/0972000547780992.jpg" Key: "profiles/0972000547780999.jpg"
(已尝试去掉CopySource中存储桶名称前的前置斜杠)
调用后收到正常响应,但文件未完成复制。相关代码如下:
async copyFile(fileSource: string, fileTarget: string, deleteSource: boolean = false ): Promise<any> { const bucket = environment.awsBucket; const s3Client = new S3Client({ region: environment.awsRegion, //credentials: fromIni({profile: 'dev'}) }); credentials: { accessKeyId: environment.awsAccessKeyS3, secretAccessKey: environment.awsSecretS3, } }); const params = { Bucket: bucket, CopySource: '/' + bucket + '/' + fileSource, Key: fileTarget, }; console.log('About to call AWS S3 copy file with: ', params); try { const results = await s3Client.send(new CopyObjectCommand(params)); console.log('Copied S3 file: ', results); if (!results) { return results; } if (deleteSource) { const paramsDelete = { Bucket: bucket, Key: fileSource, }; const resultsDelete = await s3Client.send(new DeleteObjectCommand(params)); console.log('Deleted S3 file: ', resultsDelete); return resultsDelete; } else { return results; } } catch (err) { console.log('There was an error renaming your file: ', err); return false; } }
核心问题及修复方案
DeleteObjectCommand参数错误
代码中删除操作时错误传入了复制用的params,而非定义好的paramsDelete。这会导致刚复制的目标文件被删除,而非源文件,看起来像是复制未成功。
修复:将删除操作的参数改为paramsDelete:const resultsDelete = await s3Client.send(new DeleteObjectCommand(paramsDelete));CopySource格式问题
AWS SDK v3中,CopySource的正确格式不需要前置斜杠,当源对象和目标对象在同一个桶时,格式应为${bucket}/${fileSource}。前置斜杠可能导致S3解析路径错误,虽然返回成功但实际未找到源对象。
修复:修改CopySource的拼接方式:CopySource: `${bucket}/${fileSource}`,
修复后的完整代码
async copyFile(fileSource: string, fileTarget: string, deleteSource: boolean = false ): Promise<any> { const bucket = environment.awsBucket; const s3Client = new S3Client({ region: environment.awsRegion, credentials: { accessKeyId: environment.awsAccessKeyS3, secretAccessKey: environment.awsSecretS3, } }); const params = { Bucket: bucket, CopySource: `${bucket}/${fileSource}`, Key: fileTarget, }; console.log('About to call AWS S3 copy file with: ', params); try { const results = await s3Client.send(new CopyObjectCommand(params)); console.log('Copied S3 file: ', results); if (!results) { return results; } if (deleteSource) { const paramsDelete = { Bucket: bucket, Key: fileSource, }; const resultsDelete = await s3Client.send(new DeleteObjectCommand(paramsDelete)); console.log('Deleted S3 file: ', resultsDelete); return resultsDelete; } else { return results; } } catch (err) { console.log('There was an error renaming your file: ', err); return false; } }
内容的提问来源于stack exchange,提问作者Mor Sagmon
相关产品推荐
相关产品推荐

