AWS S3 给出错误“调用链期间出现异常:无法解析请求(格式不正确(无效令牌):第 1 行,第 0 列),收到无效 XML:”

问题描述 投票:0回答:2

我正在使用 node.js 使用 localstack 将图像上传到本地环境中的 s3 存储桶

这是我的API代码:

const s3 = new AWS.S3({
  accessKeyId: 'testKEYId',
  secretAccessKey: 'testSecret',
  region: 'ap-south-1',
  sslEnabled: false,
  endpoint: 'http://localhost:4566',
});

app.post('/upload-1', upload.any(), (req, res) => {
  const imagePath = './myfolder/my-image.jpg'; // Update with your image file path
  const bucketName = 'my-buckert'; // Update with your S3 bucket name
  const remoteFileName = 'uploaded_image.jpg';

  const fileContent = fs.readFileSync(imagePath);

  console.log(fileContent);

  const params = {
    Bucket: bucketName,
    Key: remoteFileName,
    Body: fileContent,
  };

  const bucketParams = {
    Bucket: bucketName,
  }

  s3.upload(params, (err, data) => {
    if (err) {
      console.error('Error uploading image to S3:', err);
    } else {
      console.log('Image uploaded successfully. S3 location:', data.Location);
    }
  });
});

当我调用此 API 时,我收到此错误:

调用链期间出现异常:无法解析请求(格式不正确) (无效令牌):第 1 行,第 0 列),收到无效 XML:

参考截图:

node.js amazon-s3 aws-sdk localstack
2个回答
0
投票

此问题源于在使用

Virtual-Hosted
作为端点时对 LocalStack 使用
localhost
样式请求。

您的 SDK 正在将存储桶添加到您的主机,这会导致如下所示的请求:

http://my-buckert.localhost:4566/uploaded_image.jpg

如果存储桶名称后面没有
.s3.
,LocalStack 无法从您的主机解析存储桶名称,并将将此请求视为
CreateBucket
调用。

这里的文档中概述了两种解决方案: https://docs.localstack.cloud/user-guide/aws/s3/#path-style-and-virtual-hosted-style-requests

就您而言,最简单的方法是为您的客户使用

s3ForcePathStyle
。 以这种方式创建您的客户端应该可以解决您的问题:

const s3 = new AWS.S3({
  accessKeyId: 'test',  // I would advise to use `test` and `test` for the keys
  secretAccessKey: 'test',
  region: 'ap-south-1',
  sslEnabled: false,
  endpoint: 'http://localhost:4566',
  s3ForcePathStyle: true,
});

有关 javascript AWS SDK 配置的更多信息:https://docs.localstack.cloud/user-guide/integrations/sdks/javascript/


0
投票

我面临着同样的问题,@bentsku 提到的原因是正确的。在我启用 pathStyleAccess 后,一切都对我有用:)。

这是我的S3客户端创建代码

   private static AmazonS3 getLocalS3() {
    BasicSessionCredentials awsCreds = new BasicSessionCredentials("test", "test", "");
    return AmazonS3ClientBuilder.standard()
            .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:4566", "us-east-2"))
            .enablePathStyleAccess()
            .build();
}

非常感谢@bentsku

© www.soinside.com 2019 - 2024. All rights reserved.