Mau*_*ano 57 amazon-s3 amazon-web-services node.js
我需要使用AWS SDK检查文件是否存在.
这是我正在做的事情:
var params = {
Bucket: config.get('s3bucket'),
Key: path
};
s3.getSignedUrl('getObject', params, callback);
Run Code Online (Sandbox Code Playgroud)
有用.问题是当对象不存在时,回调(带有参数err和url)不会返回错误,当我尝试访问URL时,它会显示"NoSuchObject".
getSignedUrl当对象不存在时,此方法不应返回错误对象吗?
如何确定对象是否存在?我真的需要在返回的网址上拨打电话吗?
谢谢.
Cap*_*ion 94
在创建签名URL之前,您需要直接从存储桶检查文件是否存在.一种方法是通过请求HEAD元数据.
// Using callbacks
s3.headObject(params, function (err, metadata) {
if (err && err.code === 'NotFound') {
// Handle no object on cloud here
} else {
s3.getSignedUrl('getObject', params, callback);
}
});
// Using async/await (untested)
try {
const headCode = await s3.headObject(params).promise();
const signedUrl = await s3.getSignedUrl('getObject', params).promise();
// Do something with signedUrl
} catch (headErr) {
if (headErr.code === 'NotFound') {
// Handle no object on cloud here
}
}
Run Code Online (Sandbox Code Playgroud)
小智 19
没有 try/catch 块的最简单的解决方案。
const exists = await s3
.headObject({
Bucket: S3_BUCKET_NAME,
Key: s3Key,
})
.promise()
.then(
() => true,
err => {
if (err.code === 'NotFound') {
return false;
}
throw err;
}
);
Run Code Online (Sandbox Code Playgroud)
wra*_*ord 13
AFAICT 截至 2022 年 2 月,使用 JavaScript V3 SDK 执行此操作的正确方法是\n使用HeadObjectCommand.
注意:我在这里使用带有显式类型的 TypeScript,但是您可以在重构代码时删除这些显式类型……它们只是为了显示正在使用的 AWS 类型。
\nimport type {\n HeadObjectCommandInput,\n HeadObjectCommandOutput,\n} from "@aws-sdk/client-s3";\n\nimport {\n S3Client,\n HeadObjectCommand,\n} from \'@aws-sdk/client-s3\';\n\nasync function existsOnS3(\n client: S3Client,\n bucket: string,\n key: string,\n): Promise<boolean> {\n try {\n const bucketParams: HeadObjectCommandInput = {\n Bucket: bucket,\n Key: key,\n };\n const cmd = new HeadObjectCommand(bucketParams);\n const data: HeadObjectCommandOutput = await client.send(cmd);\n\n // I always get 200 for my testing if the object exists\n const exists = data.$metadata.httpStatusCode === 200;\n return exists;\n } catch (error: any) {\n if (error.$metadata?.httpStatusCode === 404) {\n // doesn\'t exist and permission policy includes s3:ListBucket\n return false;\n } else if (error.$metadata?.httpStatusCode === 403) {\n // doesn\'t exist, permission policy WITHOUT s3:ListBucket\n return false;\n } else {\n // some other error\n ...log and rethrow if you like per your requirements\n }\n }\n}\n\nRun Code Online (Sandbox Code Playgroud)\n注意:上面的catch子句故意不编译。如何处理其他错误由您决定。返回false可能会导致无声的故障,这是最糟糕的一种:它们很难排除故障,而且这是你自己的错。
如果您查看权限部分HeadObjectCommand上面链接的文档的“权限”部分,您会注意到提到了 403 和 404 响应:
\n\n您需要相关的读取对象(或版本)权限才能执行此操作。有关详细信息,请参阅在策略中指定权限。如果您请求的对象不存在,Amazon S3 返回的错误取决于您是否也具有 s3:ListBucket 权限。
\n如果您拥有存储桶的 s3:ListBucket 权限,Amazon S3 将返回 HTTP 状态代码 404(“没有此类密钥”)错误。
\n如果您不\xe2\x80\x99t 具有 s3:ListBucket 权限,Amazon S3 将返回 HTTP 状态代码 403(“访问被拒绝”)错误。
\n
我不知道除了密钥不存在之外,这些错误响应是否还可能源于其他错误。
\n跨域资源共享
\n我还必须HEAD添加AllowedMethods在存储桶上添加 CORS 权限部分
"AllowedMethods": [\n "GET",\n "PUT",\n "HEAD"\n],\nRun Code Online (Sandbox Code Playgroud)\n
通过使用headObject方法
AWS.config.update({
accessKeyId: "*****",
secretAccessKey: "****",
region: region,
version: "****"
});
const s3 = new AWS.S3();
const params = {
Bucket: s3BucketName,
Key: "filename" //if any sub folder-> path/of/the/folder.ext
}
try {
await s3.headObject(params).promise()
console.log("File Found in S3")
} catch (err) {
console.log("File not Found ERROR : " + err.code)
}
Run Code Online (Sandbox Code Playgroud)
由于参数是恒定的,因此最好将其与结合使用const。如果在s3中找不到该文件,则会引发错误NotFound : null。
如果要在存储桶中应用任何操作,则必须CORS Configuration在AWS的相应存储桶中更改的权限。用于更改权限Bucket->permission->CORS Configuration并添加此代码。
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Run Code Online (Sandbox Code Playgroud)
有关CORS配置的更多信息:https : //docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
这基于适用于 JavaScript v3 的 AWS 开发工具包。
import { S3Client } from "@aws-sdk/client-s3";
const s3Client = new S3Client({
region: "your-aws-region"
});
const checkIfFileExist = async (key) => {
try {
await s3Client.send(
new HeadObjectCommand({
Bucket: "your-bucket",
Key: key,
})
);
return true;
} catch (error) {
return false;
}
};
const doSomeProcess = async () => {
const fileExist = await checkIfFileExist("your-file.txt");
console.log(fileExist);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35517 次 |
| 最近记录: |