简体   繁体   English

如何通过 JavaScript 访问 S3 存储桶?

[英]How to access S3 bucket through JavaScript?

I've looked at some other posts and tried to replicate what they've done, but none of them seem to be running into the same issue I am.我查看了其他一些帖子并尝试复制他们所做的事情,但似乎没有一个遇到与我相同的问题。 Basically, I'm trying to store the list of keys from a S3 bucket so I can iterate through them in my Vue app.基本上,我正在尝试存储 S3 存储桶中的密钥列表,以便可以在我的 Vue 应用程序中遍历它们。 I've got the code below, and you can see I have 3 console.log statements where I'm trying to print the value of files .我有下面的代码,你可以看到我有 3 个console.log语句,我正在尝试打印files的值。 The first one prints exactly what I expect it to, while the 2nd one prints [] , and the 3rd doesn't print at all.第一个打印完全符合我的预期,而第二个打印[] ,第三个根本不打印。 So for some reason it's not persisting the value of files outside of the s3.listObjectsV2() function, which means I can't access the actual files themselves in the app.因此,由于某种原因,它不会保留s3.listObjectsV2() function 之外的files值,这意味着我无法在应用程序中访问实际文件本身。

let AWS = require("aws-sdk");
AWS.config.update({
  accessKeyId: process.env.VUE_APP_ACCESS_KEY,
  secretAccessKey: process.env.VUE_APP_ACCESS_KEY,
  region: "us-east-1",
});
let s3 = new AWS.S3();

let params = {
  Bucket: "my-bucket",
  Delimiter: "",
};

let getS3Files = () => {
  let files = [];
  s3.listObjectsV2(params, function (err, data) {
    if (data) {
      data.Contents.forEach((file) => {
        files.push({
          fileName: file.Key,
          fileDate: file.LastModified,
        });
      });
      console.log(files);
    }
  });
  console.log(files);
  if (files.length > 0) {
    files = files.sort((a, b) => b.fileDate - a.fileDate);
    console.log(files);
  }
  return files;
};

getS3Files();

It is because you are not waiting until the s3.listObjectsV2 completes fetching its data.这是因为您没有等到s3.listObjectsV2完成获取其数据。 Although s3.listObjectsV2 does not seem like a function you should wait until it completes, it needs time to send a request to s3 and get the data you requested.虽然s3.listObjectsV2看起来不像 function 您应该等到它完成,它需要时间向s3发送请求并获取您请求的数据。

In the code you provided, the second console.log will most probably execute before the first console.log and by that time you would not have any data pushed to files .在您提供的代码中,第二个console.log很可能会在第一个console.log之前执行,到那时您不会有任何数据推送到files Hence it will print [] .因此它将打印[] And before the third log, it is checking whether you have any element in your files which would again equal to false since files = [] .在第三个日志之前,它会检查files中是否有任何元素再次等于false ,因为files = []

So, you need to wrap this around a Promise and wait until it completes.因此,您需要将其包裹在 Promise 周围并等待它完成。

let getS3Files = async () => {
  let files = [];

  await new Promise(function (resolve, reject) {
    s3.listObjectsV2(params, function (err, data) {
      if (data) {
        data.Contents.forEach((file) => {
          files.push({
            fileName: file.Key,
            fileDate: file.LastModified,
          });
        });
        console.log(files);
        resolve();
      } else {
        reject(err);
      }
    });
  });
  console.log(files);
  if (files.length > 0) {
    files = files.sort((a, b) => b.fileDate - a.fileDate);
    console.log(files);
  }
  return files;
};

await getS3Files();

I am not familiar with the s3 api, but I understand listObjectsV2 is an asynchronous operation, in consequence files will be empty because it happens outside the asynchronous call and is executed before having values我不熟悉 s3 api,但我了解listObjectsV2是一个异步操作,因此files将是空的,因为它发生在异步调用之外并且在有值之前执行

Please try请试试

let AWS = require("aws-sdk");

AWS.config.update({
  accessKeyId: process.env.VUE_APP_ACCESS_KEY,
  secretAccessKey: process.env.VUE_APP_ACCESS_KEY,
  region: "us-east-1",
});

let s3 = new AWS.S3();
let params = {
  Bucket: "my-bucket",
  Delimiter: "",
};

let getS3Files = (callback) => {
  s3.listObjectsV2(params, function (err, data) {
    callback(data);
  });
};

getS3Files((data) => {
  const files = data.Contents.map((file) => ({
    fileName: file.key,
    fileDate: file.LastModified,
  })).sort((a, b) => b.fileDate - a.fileDate);

  return files;
});

In this case, the getS3Files receives a callback that will contain the data, which you will process in the function call.在这种情况下, getS3Files会收到一个包含数据的回调,您将在 function 调用中处理这些数据。

Take a look to this question How do I return the response from an asynchronous call?看看这个问题如何从异步调用中返回响应?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何让我的 HTML 文件访问 Amazon S3 存储桶中的 CSS 和 JavaScript 文件? - How can I get my HTML file to access my CSS and JavaScript files in an Amazon S3 Bucket? s3 JavaScript创建存储桶 - s3 javascript create bucket 如何通过 API 从 S3 存储桶下载私有文件 - How to dowload a private file from S3 bucket through API "如何在 JavaScript 中使用 CDK 将资源策略添加到现有 S3 存储桶?" - How to add resource policy to existing S3 bucket with CDK in JavaScript? 如何将 Amazon S3 存储桶中的 javascript 连接到 Amazon 时间服务器? - How to connect javascript in Amazon S3 bucket to Amazon time server? S3 遍历存储桶/文件夹/文件 - S3 Iterate through Bucket/Folders/Files 通过JS在S3存储桶上上传图片时,消息显示访问被拒绝的错误 - while uploading image on S3 bucket through JS, the message shows the error of access denied 在 JavaScript 中从 S3 Bucket 中读取 JSON 时没有“Access-Control-Allow-Origin”错误 - No 'Access-Control-Allow-Origin' error when reading in JSON from S3 Bucket in JavaScript 有没有办法使用 AWS Amplify 库 (JavaScript) 在没有认知用户池和身份池的情况下访问 s3 存储桶? - Is there a way to use AWS Amplify library (JavaScript) to access s3 bucket without cognito user poool and identity pool? 如何将InMemoryUploadedFile上传到我的S3 Bucket? - How to upload InMemoryUploadedFile to my S3 Bucket?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM