【问题标题】:How to upload image to amazon aws S3 using presigned Url如何使用预签名的 URL 将图像上传到亚马逊 aws S3
【发布时间】:2021-09-17 11:15:07
【问题描述】:

您好,当我尝试使用我的 vue 应用程序中的预签名 url 将图像上传到我的亚马逊 aws 存储桶时,我收到 400 错误请求错误。我已经成功生成了一个预签名的 url,但我无法使用它将图像发布到我的存储桶中。

获取预签名网址的路径

const express = require('express')
const router = new express.Router()
const requireAuth = require('../middleware/requireAuth')

router.use(requireAuth)

const v4 = require('uuid')

const AWS = require('aws-sdk')
const s3 = new AWS.S3({
    region: process.env.BUCKET_REGION,
    accessKeyId: process.env.ACCESS_KEY_ID,
    secretAccessKey: process.env.SECRET_ACCESS_KEY
})

router.get('/upload', async (req, res) => {
    const key = `${req.user._id}/${v4()}.jpeg`

    s3.getSignedUrl('putObject', {
        Bucket: 'my-post-app-bucket',
        ContentType: 'image/jpeg',
        Key: key
    }, (err, url) => res.send({ key, url }))
})

module.exports = router

Vue 客户端

<template>
  <form @submit.prevent="handleSubmit">
    <input type="file" @change="handleChange">
    <button>add</button>
  </form>
</template>

<script>
export default {
  data(){
    return {
      file: ''
    }
  },
  methods: {
    handleChange(e){
      this.file = e.target.files[0]
    },
    async handleSubmit(){
      await this.$store.dispatch('images/uploadImage', this.file)
    }
  }
}
</script>

Vuex 动作发布到预签名网址

actions: {
    async uploadImage(context, file){
      try {
        const res = await api.get('/upload', {
          headers: {
            Authorization: `Bearer ${localStorage.getItem('token')}`
          }
        })
        await axios.put(res.data.url, file, {
          headers: {
            'Content-Type': file.type
          }
        })
      }catch(err){
        console.log(err.message)
        context.commit('SET_ERROR', err.message, { root: true })
      }
    }
  }

AWS CORS 权限

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "http://localhost:8080"
        ],
        "ExposeHeaders": []
    }
]

我收到“请求失败,状态码为 400”错误。

【问题讨论】:

  • 响应正文是什么?

标签: node.js amazon-web-services vue.js amazon-s3 axios


【解决方案1】:

几周前我遇到了类似的情况,这就是我的解决方法

const formData = new FormData();
Object.entries(fields).forEach(([key, value]) => {
    formData.append(key, value);
});

formData.append('file', file.originFileObj);

axios.post(url, formData, {
    headers: {
        'Content-Type': 'multipart/form-data',
    },
})

fields 来自对generate_presigned_post 的调用

fileFile 类型的对象

【讨论】:

    猜你喜欢
    • 2018-09-12
    • 2012-07-07
    • 1970-01-01
    • 2016-01-11
    • 2017-08-01
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多