无法将带有ACL公共读取的文件上传到Digital Ocean空间

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

我正在尝试从浏览器将图像上传到 Digital Ocean 空间。这些图像应该是公开的。我能够成功上传图片。

但是,虽然ACL设置为

public-read
,但上传的文件始终是私有的

我知道它们是私有的,因为 a) 仪表板显示权限是“私有”,b) 因为公共 URL 不起作用,c) 在仪表板中手动将权限更改为“公共”可以修复所有问题。

这是我正在使用的整个流程。

  1. 在后端创建预签名 URL
  2. 将该网址发送到浏览器
  3. 将图像上传到该预签名网址

有什么想法为什么这些图像不公开吗?

代码

以下示例是用 TypeScript 编写的,并使用 AWS 的 v3 SDK。

后端

这会生成用于上传文件的预签名 URL。

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'

const client = new S3Client({
    region: 'nyc3',
    endpoint: 'https://nyc3.digitaloceanspaces.com',
    credentials: {
        accessKeyId: process.env.DIGITAL_OCEAN_SPACES_KEY,
        secretAccessKey: process.env.DIGITAL_OCEAN_SPACES_SECRET,
    },
})

const command = new PutObjectCommand({
    ACL: 'public-read',
    Bucket: 'bucket-name',
    Key: fileName,
    ContentType: mime,
})

const url = await getSignedUrl(client, command)

然后将预签名的 URL 发送到浏览器。

前端

这是客户端上实际将文件上传到 Digital Ocean 的代码。

file
是一个 File 对象

const uploadResponse = await fetch(url, {
    headers: {
        'Content-Type': file.type,
        'Cache-Control': 'public,max-age=31536000,immutable',
    },
    body: file,
    method: 'PUT',
})

元数据

  • AWS 开发工具包:3.8.0
amazon-s3 aws-sdk digital-ocean digital-ocean-spaces
4个回答
10
投票

事实证明,对于 Digital Ocean,您还需要将

public-read
ACL 设置为 put 请求中的标头。

//front-end
const uploadResponse = await fetch(url, {
    headers: {
        'Content-Type': file.type,
        'Cache-Control': 'public,max-age=31536000,immutable',
        'x-amz-acl': 'public-read', // add this line
    },
    body: file,
    method: 'PUT',
})

1
投票

我没有评论的声誉,因此添加回复。谢谢@Nick ...这是我见过的 DigitalOcean 预签名 url 的少数可用代码示例之一。虽然此处官方 DigitalOcean 描述提到使用预签名网址上传需要

Content-Type
,但没有示例代码

另一个阻止我在 DigitalOcean 中使用预签名 URL 上传文件的错误是使用

'Content-Type':'multipart/form-data'
FormData()

看到这篇文章后,我遵循了@Nick的建议,使用

File()
对象和
'Content-Type':'<relevant_mime>'
。然后,文件上传就神奇了。这在官方文档中也没有涉及。


0
投票

尝试在数字海洋空间中强制将 ACL 公开:

s3cmd --access_key=YOUR_ACCESS_KEY --secret_key=YOUR_SECRET_KEY --host=YOUR_BUCKET_REGION.digitaloceanspaces.com --host-bucket=YOUR_BUCKET_NAME.YOUR_BUCKET_REGION.digitaloceanspaces.com --region=YOUR_BUCKET_REGION setacl s3://YOUR_BUCKET_NAME --acl-public

0
投票

没有足够的声誉来发表评论,但非常感谢@nick 的帮助。 这就像一个魅力。我添加了

 ContentType: ' Headers: {
    'Content-Type': file.type,
    'Cache-Control': 'public,max-age=31536000,immutable',
    'x-amz-acl': 'public-read', // add this line
  },
  ContentType: '<relevant_mime>',',

效果很好<3

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