如何确定对象是否存在AWS S3 Node.JS sdk

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)

  • 对于其他任何人-这是一个访问问题,但您所需的访问权限并不明显-实际上是`ListBucket`,这是必需的https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.htm (4认同)
  • 我收到了“禁止”代码,而不是“未找到”代码 (2认同)
  • @shadi 您需要对该对象的读取权限([headObject docs](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#headObject-property)),“禁止”意味着您不t 有权访问该对象。 (2认同)

小智 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.

\n

注意:我在这里使用带有显式类型的 TypeScript,但是您可以在重构代码时删除这些显式类型……它们只是为了显示正在使用的 AWS 类型。

\n
import 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\n
Run Code Online (Sandbox Code Playgroud)\n

注意:上面的catch子句故意不编译。如何处理其他错误由您决定。返回false可能会导致无声的故障,这是最糟糕的一种:它们很难排除故障,而且这是你自己的错

\n

如果您查看权限部分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

跨域资源共享

\n

我还必须HEAD添加AllowedMethods在存储桶上添加 CORS 权限部分

\n
"AllowedMethods": [\n    "GET",\n    "PUT",\n    "HEAD"\n],\n
Run Code Online (Sandbox Code Playgroud)\n


ban*_*der 5

通过使用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


nnt*_*ona 5

这基于适用于 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)