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


77

我需要使用AWS开发工具包检查文件是否存在。这是我在做什么:

var params = {
    Bucket: config.get('s3bucket'),
    Key: path
};

s3.getSignedUrl('getObject', params, callback);

它可以工作,但问题是当对象不存在时,回调(带有err和url参数)不会返回错误,并且当我尝试访问URL时,它会显示“ NoSuchObject”。

getSignedUrl当对象不存在时,该方法是否应该返回错误对象?如何确定对象是否存在?我真的需要打电话给返回的URL吗?


1
我确定当对象不存在时不返回错误是有原因的。这肯定是一个痛苦的屁股!
阿德里安·林奇

Answers:


122

在创建签名的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 = s3.getSignedUrl('getObject', params);
  // Do something with signedUrl
} catch (headErr) {
  if (headErr.code === 'NotFound') {
    // Handle no object on cloud here  
  }
}

1
@shadi您需要对该对象(headObject docs)具有读取权限,“ Forbidden”表示您无权访问该对象。
Marc

我认为我具有完全访问权限,但不确定。很久以前
shadi

@shadi我认为不是。...您可能有权访问文件,但不能访问文件夹。
CaptEmulation

6
对于其他任何人-这是一个访问问题,但您所需的访问权并不明显-实际上ListBucket这是必需的 docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.htm
James Lelyveld,

1
在Async Await版本中,getSignedUrl ....显然不需要.promise()。我不确定为什么我只执行s3.getSignedUrl('getObject',params)的其他古玩东西,它不会返回完整的URL ...似乎调用headObject有必要找回完整的签名URL。 ..不是吗?
koalaok

10

没有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;
    }
  );

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)
}

由于参数是恒定的,因此最好与结合使用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>

有关CORS配置的更多信息:https : //docs.aws.amazon.com/AmazonS3/latest/dev/cors.html


2

您还可以将waitFor方法与state一起使用objectExists。这将在S3.headObject()内部使用。

var params = {
  Bucket: config.get('s3bucket'),
  Key: path
};
s3.waitFor('objectExists', params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(data);           // successful response
});

1

使用getObject方法如下:

var params = {
    Bucket: config.get('s3bucket'),
    Key: path
};
s3.getObject(params, function(err, data){
    if(err) {
        console.log(err);
    }else {
      var signedURL = s3.getSignedUrl('getObject', params, callback);
      console.log(signedURL);
   }
});

10
这将检索完整的对象。最好使用HEAD请求,如@CaptEmulation所述。
尤金·纳戈尔尼

0

在Node.js中对S3进行同步调用,而不是使用Promise进行异步调用

var request = require("request");
var AWS = require("aws-sdk");

AWS.config.update({
    accessKeyId: "*****",
    secretAccessKey: "********"
});


const s3 = new AWS.S3();


var response;

function initialize(bucket,key) {
    // Setting URL and headers for request
    const params = {
        Bucket: bucket,
        Key: key
    };
    // Return new promise 
    return new Promise(function(resolve, reject) {
        s3.headObject(params, function(err, resp, body) {  
            if (err) {  
                console.log('Not Found : ' + params.Key );
                reject(params.Key);
            } else {  
                console.log('Found : ' + params.Key );
                resolve(params.Key);
            }
          })
    })
}

function main() {

    var foundArray = new Array();
    var notFoundArray = new Array();
    for(var i=0;i<10;i++)
    {
        var key = '1234'+ i;
        var initializePromise = initialize('****',key);
        initializePromise.then(function(result) {
            console.log('Passed for : ' + result);
            foundArray.push(result);
            console.log (" Found Array : "+ foundArray);
        }, function(err) {
            console.log('Failed for : ' + err);
            notFoundArray.push(err);
            console.log (" Not Found Array : "+ notFoundArray);
        });
    }


}

main();

0

同步推入操作

var request = require("request");
var AWS = require("aws-sdk");

AWS.config.update({
    accessKeyId: "*****",
    secretAccessKey: "***"
});


const s3 = new AWS.S3();


var response;

function initialize(bucket,key) {
    // Setting URL and headers for request
    const params = {
        Bucket: bucket,
        Key: key
    };
    // Return new promise 
    return new Promise(function(resolve, reject) {
        s3.putObject(params, function(err, resp, body) {  
            if (err) {  
                reject();
            } else {  
                resolve();
            }
          })
    })
}

function main() {

    var promiseArray = [];
    var prefix = 'abc/test/';
    for(var i=0;i<10;i++)
    {
        var key = prefix +'1234'+ i;
        promiseArray[i] = initialize('bucket',key);
        promiseArray[i].then(function(result) {
            console.log (" Successful ");
        }, function(err) {
            console.log (" Error ");
        });
    }


      console.log('Promises ' + promiseArray);


    Promise.all(promiseArray).then(function(values) {
        console.log("******TESTING****");
      });


}


main();

0

保证全部无故障同步运行

var request = require("request");
var AWS = require("aws-sdk");

AWS.config.update({
    accessKeyId: "*******",
    secretAccessKey: "***********"
});


const s3 = new AWS.S3();


var response;

function initialize(bucket,key) {
    // Setting URL and headers for request
    const params = {
        Bucket: bucket,
        Key: key
    };
    // Return new promise 
    return new Promise(function(resolve, reject) {
        s3.headObject(params, function(err, resp, body) {  
            if (err) {  
                resolve(key+"/notfound");
            } else{
                resolve(key+"/found");
            }
          })
    })
}

function main() {

    var foundArray = new Array();
    var notFoundArray = new Array();
    var prefix = 'abc/test/';
    var promiseArray = [];
    try{
    for(var i=0;i<10;i++)
    {
        var key = prefix +'1234' + i;
        console.log("Key : "+ key);
        promiseArray[i] = initialize('bucket',key);
        promiseArray[i].then(function(result) {
            console.log("Result : " + result);
            var temp = result.split("/");
            console.log("Temp :"+ temp);
            if (temp[3] === "notfound")
            {
                console.log("NOT FOUND");
            }else{
                console.log("FOUND");
            }

        }, function(err) {
            console.log (" Error ");
        });
    }

    Promise.all(promiseArray).then(function(values) {
        console.log("^^^^^^^^^^^^TESTING****");
      }).catch(function(error) {
          console.error(" Errro : "+ error);
      });




}catch(err){
    console.log(err);
}


}

main();

不同步。
肖恩
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.