我正在try 将图像文件上传到AWS S3存储桶.我正在使用Node/Express生成一个预先签名的URL,以便从Reaction前端将所述图像直接上传到S3.问题是,我可以上传的文件作为一个文件(大小相同的本地PC),但它没有文件扩展名.也就是说,它只有带符号的字符,例如文件类型为9c9743b9-4dd7-4afa-af06-c060fb0fb175的文件,而不是文件类型为PNG的9c9743b9-4dd7-4afa-af06-c060fb0fb175.png

以下是我到目前为止try 过的一小段内容

后端

// My controller
try {
  const payload = await AwsS3Service.getSignedUrlService();
  res.status(200).send({ 
      success: true, 
      data: payload
  });
  ...
const s3 = new aws.S3({
  region: config.awsS3.region,
  accessKeyId: config.awsS3.accessKeyId,
  secretAccessKey: config.awsS3.secretAccessKey,
  signatureVersion: config.awsS3.signatureVersion
})

const getSignedUrlService = async () => {
  const imageName = crypto.randomUUID()

  const params = ({
    Bucket: config.awsS3.bucketName,
    Key: imageName,
    Expires: 120 // in sec
  })

  const uploadUrl = await s3.getSignedUrlPromise('putObject', params)
  return uploadUrl
}

前端

  const [final, setFinal] = useState<FileList | any>('')
  const [img, setImg] = useState<typeof formState.file>(null)

  const handleImageChange = (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files && e.target.files[0]
    if (e.target.files) { 
      setFinal(e.target.files[0]!)
    }
    const { type, name } = file as File
    setImgName(name)
    setImgType(type)

    const fileReader = new FileReader()
    fileReader.onload = (e) => {
      setImg(e.target?.result)
    }
    fileReader.readAsDataURL(file as Blob)
  }

  const handleFormSubmit: SubmitHandler<IImage> = async (data: IImage) => {
    
    try {
      const signedUrl = await axios({ method: 'GET', url: `${config.API_URL}/awss3` })
      
      const formData = new FormData()
      formData.append('file', final[0])   

      const resUpload = await fetch(`${signedUrl.data.data}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'multipart/form-data' },
        body: final
      })

      if (resUpload.status === 200) {
        // redirect
      }
    } catch(err: any) {
      alert(`An error occured. ${err.message}`)
    }
  }

  return (
    <form onSubmit={e => e.preventDefault()}>
      <Stack>
        <Box>
            <InputLabel htmlFor='imgfile'>Image File</InputLabel>
            <picture>
              { img 
                ? <img src={img} alt='Image preview' height={90} width={160} /> 
                : <Box sx={{ height: 90, width: 160, backgroundColor: '#555' }}></Box>
              }
            </picture>
            <input type='file' accept='image/*' id='imgfile' name='imgFile' onChange={handleImageChange} />
        </Box>
      </Stack>
      <Button type='submit' onClick={handleSubmit(handleFormSubmit)}>
        Submit
      </Button>
    </form>
  )

我已经有一段时间无法解决这个问题了.任何帮助都是非常感激的.感谢您的阅读.

推荐答案

发布这篇文章是为了以防万一有人对此感兴趣.

我设法解决了这个问题,方法是在将签名请求作为POST请求时添加文件名、类型和扩展名,并在请求正文中附加文件名和文件类型.

// Frontend
const signedUrl = await axios({
    method: 'POST',
    url: `${config.API_URL}/awss3`,
    headers: { 'Content-Type': 'application/json' },
    data: { name: imgName, type: imgType }
})

并将它们添加到Key

// Backend
const getSignedUrlService = async (name, type) => {
  // name and type from req.body
  const imageName = crypto.randomUUID() + '-' + name

  const params = ({
    Bucket: config.awsS3.bucketName,
    Key: imageName,
    ContentType: type,
    Expires: 120 // in sec
  })

  const uploadUrl = await s3.getSignedUrlPromise('putObject', params)
  return uploadUrl
}

感谢每一个帮助过我的人

Node.js相关问答推荐

链接Inbox类方法,范围在哪里以及为什么发生变化?

使用NodeJS在S3上传文件时的格式问题

@nuxtjs/站点 map 错误提示:找不到包';NitroPack';

为什么在导出的函数中调用node-sqlite3中的数据库方法时不起作用?

控制台显示一个长对象,我可以';每当我发布更新Mongoose数据库的请求时,我都不知道错误是什么,

如何使用NodeJS在mongodb中更新文档

使用 axios 和 Cheerio (Node js) 抓取 google 搜索

如何在 JavaScript 中显示多维数组中使用的一维数组的变量名?

如何使用包含条件正确分页的 sequelize 查询?

错误:无法为 /blog 收集页面数据并且在 object.fetch 处获取失败

使用 fs.createWriteStream 将数据写入 bigquery (node.js) 时出现模式错误

Typescript typeRoots 未检测到类型定义

为什么 $or 在带有正则表达式的mongoose 中不能正常工作

使用 Node.js 在 MongoDB 中搜索

node.js 变量不存在代码块

等到文件上传完成的有效方法(mongoose )

node和mongoDB聚合数据时的输入字段函数

Ansible 将以什么用户身份运行我的命令?

在 Mongoose 中创建外键关系

按日期时间字段获取最新的 MongoDB 记录