Невозможно загрузить файлы с ACL для публичного чтения в пространства Digital Ocean.
Я пытаюсь загрузить изображения в пространство Digital Ocean из браузера. Эти изображения должны быть общедоступными. Я могу успешно загрузить изображения.
Однако, хотя ACL установлен на
public-read
, загруженные файлы всегда являются личными.
Я знаю, что они частные, потому что а) на приборной панели указано, что разрешения являются «частными», и б) потому, что общедоступные URL-адреса не работают, и в) ручное изменение разрешений на «общедоступные» на приборной панели все исправляет.
Вот общий процесс, который я использую.
- Создайте предварительно подписанный URL-адрес на бэкэнде
- Отправьте этот URL в браузер
- Загрузите изображение на этот предварительно подписанный URL
Есть идеи, почему изображения не публикуются?
Код
Следующие примеры написаны на TypeScript и используют SDK AWS v3.
Бэкэнд
Это создает предварительно подписанный 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
является файловым объектом .
const uploadResponse = await fetch(url, {
headers: {
'Content-Type': file.type,
'Cache-Control': 'public,max-age=31536000,immutable',
},
body: file,
method: 'PUT',
})
Метаданные
- AWS SDK: 3.8.0
3 ответа
Оказывается, для Digital Ocean также необходимо установить
public-read
ACL в качестве заголовка в запросе на размещение.
//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',
})
У меня нет репутации, чтобы комментировать, поэтому добавляю ответ. Спасибо, @Nick ... это один из немногих рабочих примеров кода, который я видел для предварительно подписанного URL-адреса DigitalOcean. Хотя в официальном описании DigitalOcean здесь упоминается
Content-Type
необходим для загрузки с предварительно подписанными URL-адресами, пример кода отсутствует .
Еще одна ошибка, из-за которой мне не удалось загрузить файл, используя предварительно подписанные URL-адреса в DigitalOcean, заключалась в использовании
'Content-Type':'multipart/form-data'
а также
FormData()
.
Увидев этот пост, я последовал предложению @Nика использовать
File()
объект и
'Content-Type':'<relevant_mime>'
. Затем загрузка файла прошла отлично. Это также не рассматривается в официальных документах.
Попробуйте сделать это, чтобы сделать ACL общедоступным в Digital Ocean Spaces:
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