So stellen Sie fest, ob ein Objekt vorhanden ist AWS S3 Node.JS sdk


73

Ich muss mit AWS SDK überprüfen, ob eine Datei vorhanden ist. Folgendes mache ich:

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

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

Es funktioniert, aber das Problem ist, dass wenn das Objekt nicht existiert, der Rückruf (mit den Argumenten err und url) keinen Fehler zurückgibt und wenn ich versuche, auf die URL zuzugreifen, "NoSuchObject" angezeigt wird.

Sollte diese getSignedUrlMethode nicht ein Fehlerobjekt zurückgeben, wenn das Objekt nicht vorhanden ist? Wie stelle ich fest, ob das Objekt vorhanden ist? Muss ich die zurückgegebene URL wirklich anrufen?


1
Ich bin sicher, dass es einen Grund gibt, keinen Fehler zurückzugeben, wenn das Objekt nicht vorhanden ist. Es ist sicher ein Schmerz im Hintern!
Adrian Lynch

Antworten:


118

Bevor Sie die signierte URL erstellen, müssen Sie überprüfen, ob die Datei direkt aus dem Bucket vorhanden ist. Eine Möglichkeit, dies zu tun, besteht darin, die HEAD-Metadaten anzufordern.

// 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 Sie benötigen Lesezugriff auf das Objekt ( headObject-Dokumente ). "Verboten" bedeutet, dass Sie keinen Zugriff auf dieses Objekt haben.
Marc

Ich glaube, ich hatte vollen Zugriff, bin mir aber nicht sicher. Es ist so lange her
Shadi

@shadi Ich glaube nicht ... Sie hatten möglicherweise Zugriff auf Dateien, aber nicht auf die Ordner.
CaptEmulation

5
Für alle anderen, die dazu kommen - es ist ein Zugriffsproblem, aber es ist nicht klar, welchen Zugriff Sie benötigen - es ist tatsächlich ListBucketerforderlich, docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.htm
James Lelyveld

1
In der Async Await-Version benötigt getSignedUrl .... anscheinend keine .promise (). Andere Kuriositäten, bei denen ich mir nicht sicher bin, warum, wenn ich nur s3.getSignedUrl ('getObject', params) ausführe, nicht die vollständige URL zurückgegeben wird ... scheint, dass der Aufruf headObject erforderlich ist, um die vollständig signierte URL zurückzugewinnen. .. ist es nicht?
Koalaok

8

Die einfachste Lösung ohne Try / Catch-Block.

const exists = await s3
  .headObject({
    Bucket: S3_BUCKET_NAME,
    Key: s3Key,
  })
  .promise()
  .then(
    () => true,
    err => {
      if (err.code === 'NotFound') {
        return false;
      }
      throw err;
    }
  );

5

mit headObjectMethode

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

Da Parameter konstant sind, ist dies der beste Weg, um sie zu verwenden const. Wird die datei nicht in s3 gefunden, wird der fehler ausgegeben NotFound : null.

Wenn Sie Vorgänge im Bucket anwenden möchten, müssen Sie die Berechtigungen CORS Configurationim jeweiligen Bucket im AWS ändern . Zum Ändern von Berechtigungen Bucket->permission->CORS Configurationund Hinzufügen dieses Codes.

<CORSConfiguration>
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Weitere Informationen zur CORS-Konfiguration finden Sie unter https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html


2

Sie können die waitForMethode auch zusammen mit dem Status verwenden objectExists. Dies wird S3.headObject()intern verwendet.

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

Verwenden Sie folgende getObjectMethode:

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
Dadurch wird das vollständige Objekt abgerufen. Verwenden Sie besser die HEAD-Anforderung als @CaptEmulation.
Eugene Nagorny

0

Synchroner Aufruf von S3 in Nodejs anstelle eines asynchronen Aufrufs mit 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

Synchroner Put-Betrieb

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

Promise.All ohne Fehler Synchronbetrieb

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();

Nicht synchron.
Sean
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.