无法使用 ACL public-read 上传文件到 Digital Ocean 空间
Cannot upload files with ACL public-read to Digital Ocean spaces
我正在尝试从浏览器将图像上传到 Digital Ocean space。这些图片应该是 public。我可以成功上传图片了。
但是,虽然ACL设置为public-read
,上传的文件始终是私有的.
我知道它们是私有的,因为 a) 仪表板显示权限是“私有的”,并且 b) 因为 public urls 不起作用,并且 c) 手动在仪表板中将权限更改为“public”可修复所有问题。
这是我使用的整个流程。
- 在后端创建预签名URL
- 将 url 发送到浏览器
- 将图像上传到预签名 url
知道为什么图像不是 public 吗?
代码
以下示例使用 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 object.
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
事实证明,对于 Digital Ocean,您还需要在 put 请求中将 public-read
ACL 设置为 header。
//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',
})
尝试在 Digital Ocean Spaces 中将 ACL 强制设为 Public:
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
我没有发表评论的名誉,因此添加了回复。谢谢@Nick ...这是我为 DigitalOcean 预签名 url 看到的为数不多的代码示例之一。虽然 official DigitalOcean description here 提到使用预签名 url 上传需要 Content-Type
,但没有示例代码。
阻止我在 DigitalOcean 中使用预签名 URL 上传文件的另一个错误是使用 'Content-Type':'multipart/form-data'
和 FormData()
.
看到这个 post 之后,我听从了@Nick 的建议,使用 File()
对象和 'Content-Type':'<relevant_mime>'
。然后,文件上传就像一个魅力。这在官方文档中也没有涉及。
我正在尝试从浏览器将图像上传到 Digital Ocean space。这些图片应该是 public。我可以成功上传图片了。
但是,虽然ACL设置为public-read
,上传的文件始终是私有的.
我知道它们是私有的,因为 a) 仪表板显示权限是“私有的”,并且 b) 因为 public urls 不起作用,并且 c) 手动在仪表板中将权限更改为“public”可修复所有问题。
这是我使用的整个流程。
- 在后端创建预签名URL
- 将 url 发送到浏览器
- 将图像上传到预签名 url
知道为什么图像不是 public 吗?
代码
以下示例使用 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 object.
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
事实证明,对于 Digital Ocean,您还需要在 put 请求中将 public-read
ACL 设置为 header。
//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',
})
尝试在 Digital Ocean Spaces 中将 ACL 强制设为 Public:
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
我没有发表评论的名誉,因此添加了回复。谢谢@Nick ...这是我为 DigitalOcean 预签名 url 看到的为数不多的代码示例之一。虽然 official DigitalOcean description here 提到使用预签名 url 上传需要 Content-Type
,但没有示例代码。
阻止我在 DigitalOcean 中使用预签名 URL 上传文件的另一个错误是使用 'Content-Type':'multipart/form-data'
和 FormData()
.
看到这个 post 之后,我听从了@Nick 的建议,使用 File()
对象和 'Content-Type':'<relevant_mime>'
。然后,文件上传就像一个魅力。这在官方文档中也没有涉及。