从 Nuxt 上传到 AWS S3 存储桶时出现 500 内部服务器错误

Posted

技术标签:

【中文标题】从 Nuxt 上传到 AWS S3 存储桶时出现 500 内部服务器错误【英文标题】:500 Internal Server Error when uploading to an AWS S3 bucket from Nuxt 【发布时间】: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 配置

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

【问题讨论】:

见***.com/a/45356752/441757 【参考方案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】:

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

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

【讨论】:

以上是关于从 Nuxt 上传到 AWS S3 存储桶时出现 500 内部服务器错误的主要内容,如果未能解决你的问题,请参考以下文章

从托管在 S3 存储桶上的站点访问 AWS API 时出现 CORS 问题 [关闭]

使用 AlamoFire 和预签名 URL 将图像上传到 S3 存储桶时出现问题

上传时出现 Amazon S3 存储桶 MalformedXML 错误

尝试从 aws ec2 客户端访问存储桶时出现位置约束异常

有没有办法从 Web 表单快速上传到 S3 AWS 存储桶?

使用带有 Node.js 的 AWS Lambda 函数从 S3 存储桶中提取 zip 文件并上传到另一个存储桶