【问题标题】:500 Internal Server Error when uploading to an AWS S3 bucket from Nuxt从 Nuxt 上传到 AWS S3 存储桶时出现 500 内部服务器错误
【发布时间】:2021-06-02 19:38:44
【问题描述】:

我正在尝试使用来自 Nuxt 应用程序的 Vue 组件的 aws-sdk v3 将文件上传到 AWS S3。

这是我上传的方式。

<script>
export default {
...
methods: {
onSubmit(event) {
    event.preventDefault()
    this.addPhoto()
},
addPhoto() {
  // Load the required clients and packages
  const { CognitoIdentityClient } = require('@aws-sdk/client-cognito-identity')
  const { fromCognitoIdentityPool } = require('@aws-sdk/credential-provider-cognito-identity')
  const {
    S3Client,
    PutObjectCommand,
    ListObjectsCommand,
    DeleteObjectCommand,
  } = require('@aws-sdk/client-s3')

  const REGION = 'us-east-1' // REGION
  const albumBucketName = 'samyojya-1'
  const IdentityPoolId = 'XXXXXXX'

  const s3 = new S3Client({
    region: REGION,
    credentials: {
      accessKeyId: this.$config.CLIENT_ID,
      secretAccessKey: this.$config.CLIENT_SECRET,
      sessionToken: localStorage.getItem('accessToken'),
    },
  })

  var file = this.formFields[0].fieldName
  var fileName = this.formFields[0].fieldName.name
  var photoKey = 'user-dp/' + fileName
  var s3Response = s3.send(
    new PutObjectCommand({
      Bucket: albumBucketName,
      Key: photoKey,
      Body: file,
    }),
  )
  s3Response
    .then((response) => {
      console.log('Successfully uploaded photo.' + JSON.stringify(response))
    })
    .catch((error) => {
      console.log(
        'There was an error uploading your photo: Error stacktrace' + JSON.stringify(error.message),
      )
      const { requestId, cfId, extendedRequestId } = error.$metadata
      console.log({ requestId, cfId, extendedRequestId })
    })
},

...

}
</script>

现在的问题是浏览器抱怨 CORS。

这是我在 AWS S3 上的 CORS 配置

  1. 我在使用 SDK 创建上传请求时有些怀疑。 (我愿意使用比我现在使用的更好的 API)。
  2. 允许 CORS 的 Nuxt 设置。
  3. S3 CORS 配置中权限的其他内容
  4. chrome 开发工具上的网络选项卡显示预取的内部服务器错误 (500)。 (不知道为什么我们在这里看到 2 个条目) 感谢有关如何调试此问题的任何指示。

【问题讨论】:

标签: vue.js amazon-s3 nuxt.js amazon-cognito http-status-code-500


【解决方案1】:

我今天遇到了同样的问题。 S3 日志说它返回了 200 代码响应,但 Chrome 看到的是 500 响应。在 Safari 中,错误显示为:

received 'us-west-1'; expected 'eu-west-1'

在创建 S3 服务时将 region: 'eu-west-1'(即创建 bucked 的区域)添加到参数解决了我的问题。

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-region.html#setting-region-constructor

【讨论】:

  • 感谢分享。我刚刚注意到我的 s3 存储桶确实指向了不同的区域。现在我的错误从 500 变为 403。我想说这仍然是一个进步。等待访问日志出现以进一步调试。将恢复。
  • 这就是我在S3接入日志中看到的东西......“A1BC55FCAE7BA9ACA6E082E6F5A007DFA28AA6F0470F9E19E Samyojya-1 [06/46:44 +0000] 49.206.4.117 - KSM4CMAWAYZC7CY2 REST.OPTIONS.PREFLING - “选项/ http / 1.1”403 AccessForbiderbidder 514 - 19 - “dev.samyojya.com:3000”Mozilla / 5.0(X11; Linux X86_64)AppleWebkit / 537.36(如壁虎)Chrome / 90.0.4430.93 Safari / 537.36“ - C5UQA8CS0MCQUYP5G5UBRWWGYLOV5G6MBCEB7RPP3KRNMQYWG4WTI + xLp+ldO2HwvifksZ6PAio= - ECDHE-RSA-AES128-GCM-SHA256 - samyojya-1.s3.ap-south-1.amazonaws.com TLSv1.2"
【解决方案2】:

在存储桶策略中使用这个

 {
"Version": "2008-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": [
            "s3:GetObjectAcl",
            "s3:GetObject",
            "s3:PutObject",
            "s3:PutObjectAcl",
            "s3:ListMultipartUploadParts"
        ],
        "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*",
        "Condition": {
            "StringLike": {
                "aws:Referer": "https://example/*"
            }
        }
    }
]}

并使用存储桶的区域

const s3 = new aws.S3({
    apiVersion: 'latest',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID_CUSTOM,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY_CUSTOM,
    region: 'us-west-1',
})

【讨论】:

  • 我尝试更改存储桶策略。看到同样的错误。 @加布里埃尔。 aws.S3 看起来像 v2 - 旧版本。我正在使用 v3。
【解决方案3】:

我遇到了同样的问题,但根据文档,您应该使用 Cognito Identity 来访问存储桶。只有在 V3 中,客户端才能从浏览器访问存储桶,您必须使用 Cognito Identity 对用户进行身份验证才能访问存储桶/对象命令。目前正在尝试实施,所以我不是100%如何做到这一点只是过程。随意看看。我希望这有帮助。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Cognito SDK 链接:| https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html |示例:| https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-browser-credentials-cognito.html

【讨论】:

  • 这是一个很好的建议,我觉得。我会试一试。我唯一的挑战是在 Cognito 身份对象中找出 Cognito 用户池客户端的“登录”提供程序对象。
  • 如果您知道了,请随时给我回信。我仍在为此苦苦挣扎,因此如果您弄清楚了,将很高兴获得一些见解。谢谢!
【解决方案4】:

该错误需要在后端修复,因为它是 CORS。它清楚地说明了Access-Control-Allow-Origin 的缺失标头。
因此,在 AWS 官方文档中查看它会给您答案:https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

【讨论】:

  • 你对后端部分@kissu 是正确的。这里的后端是 aws s3。 aws-sdk 的 s3 客户端调用 s3 服务器。 s3 服务器需要返回 v3 存储桶权限 - CORS 策略中配置的标头。诡异的! :-/
  • 是的,去你的后端仪表板并编辑它以允许所需的标题!
  • 我现在找到你了。我在 s3 存储桶权限 CORS 策略中将“AllowedHeaders”参数重置为“Access-Control-Allow-Origin”并尝试上传。它不起作用。
  • 我在 s3 存储桶上启用了服务器访问日志。会看看那里是否有有趣的东西出现。收集和传递日志似乎需要一些时间。
【解决方案5】:

我在这里做错了很多事情。这篇文章的每个答案都帮助我在调试时取得了一些进展。感激不尽!

  1. 我的存储桶策略未使用基于角色的 ALLOW/DENY,它必须与我的 cognito 身份池中的已验证角色相对应。
  2. 需要将身份验证提供程序正确配置为 Cognito 用户池。
  3. 确保区域正确。 Cognito 区域可能与 S3 区域不同。
  4. 确保 CORS 政策包含“Access-Control-Allow-Origin”等相关信息。
  5. 仔细检查令牌是否包含正确的凭据。这非常方便cognito decode-verify
  6. 是从浏览器进行的独立测试。但这不是一个好方法。使用 API 服务器获取文件并从那里推送到 S3。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2013-07-06
    • 2017-08-08
    • 2015-12-07
    • 2013-07-06
    • 2015-10-28
    相关资源
    最近更新 更多