Я пытаюсь реализовать функцию загрузки изображений для приложения Vue, используя AWS S3 предварительно подписанный URL-адрес. Первым шагом является отправка запроса в API, который создаст подписанный URL для загрузки файла. Эта часть работает нормально:
Сторона сервера:
'use strict';
const aws = require('aws-sdk');
const config = require('../config');
const util = require('./util');
const uuidv4 = require('uuid/v4');
const bucketName = 'myAmazonS3Bucket';
aws.config.update({
secretAccessKey: config.AWS_SECRET_ACCESS_KEY,
accessKeyId: config.AWS_ACCESS_KEY_ID,
region: 'us-west-2'
});
const s3 = new aws.S3({ signatureVersion: 'v4' });
const handler = async (event) => {
console.log('Uploading file...');
return await getUploadURL();
}
const getUploadURL = async () => {
const actionId = uuidv4();
const s3Params = {
Bucket: bucketName,
Key: `${actionId}.jpg`,
ContentType: 'image/jpeg',
ACL: 'public-read'
};
console.log(s3Params);
return new Promise((resolve, reject) => {
let uploadURL = s3.getSignedUrl('putObject', s3Params);
console.log(uploadURL);
resolve({
"statusCode": 200,
"isBase64Encoded": false,
"headers": { "Access-Control-Allow-Origin": "*" },
"body": JSON.stringify({
"uploadURL": uploadURL,
"photoFilename": `${actionId}.jpg`
})
});
reject({
"statusCode": 500,
"headers": { "Access-Control-Allow-Origin": "*" },
"body": "A funky error occurred and I am not happy about it!"
})
});
}
module.exports = {
handler
}
Конечная точка API отправляет ответ, подобный этому:
{
"uploadURL": "https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/7925d452-cadd-4f06-ba63-cc50645e3cfb.jpg?AWSAccessKeyId=AKIASGDJJ5ZLUVPMUYMQ&Content-Type=image%2Fjpeg&Expires=1580276753&Signature=3rqNckP4DiL6DkWPRuEGJsuIGpw%3D&x-amz-acl=public-read",
"photoFilename": "7925d452-cadd-4f06-ba63-cc50645e3cfb.jpg"
}
Клиент будет использовать uploadUrl для загрузить файл в корзину S3. Вот код клиента для этого:
uploadImage: async function (e) {
console.log('Upload clicked')
console.log(e)
// Get the presigned URL
const response = await axios({
method: 'POST',
url: API_ENDPOINT
})
console.log('Response: ', response.data)
console.log('Uploading: ', this.image)
let binary = atob(this.image.split(',')[1])
let array = []
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i))
}
let blobData = new Blob([new Uint8Array(array)], {type: 'image/jpeg'})
console.log('Uploading to: ', response.data.uploadURL)
const result = await fetch(response.data.uploadURL, {
method: 'PUT',
headers: {
'Content-Type': 'image/jpeg',
'x-amz-acl': 'public-read' },
body: blobData
})
console.log('Result: ', result)
// Final URL for the user doesn't need the query string params
this.uploadURL = response.data.uploadURL.split('?')[0]
}
К сожалению, я получаю запрещенную ошибку 403 при использовании подписанного URL. Вот результат ошибок консоли, которые я получаю из моего Chrome браузера:
Загрузка в: https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/b1bdb5e3-7f64-49f7-b779-11b3f67317ee.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASGDJJ5ZLUVPMUYMQ%2F20200129%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200129T165522Z&X-Amz-Expires=900&X-Amz-Signature=b230c9a40065585307e150655466bbab3d0d99aa43f8620377ab977eb1c7234c&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read
Pi c. vue? 937b: 60 ВАРИАНТОВ https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/b1bdb5e3-7f64-49f7-b779-11b3f67317ee.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASGDJJ5ZLUVPMUYMQ%2F20200129%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200129T165522Z&X-Amz-Expires=900&X-Amz-Signature=b230c9a40065585307e150655466bbab3d0d99aa43f8620377ab977eb1c7234c&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read 403 (Запрещено)
Доступ к выборке в 'https://s3.us-west-2.amazonaws.com/pics.amazon-clone.io/b1bdb5e3-7f64-49f7-b779-11b3f67317ee.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASGDJJ5ZLUVPMUYMQ%2F20200129%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20200129T165522Z&X-Amz-Expires=900&X-Amz-Signature=b230c9a40065585307e150655466bbab3d0d99aa43f8620377ab977eb1c7234c&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read' из источника 'http://localhost : 8080 'было заблокировано политикой CORS: Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Если непрозрачный ответ отвечает вашим потребностям, установите режим запроса «no-cors», чтобы получить ресурс с отключенным CORS.