#javascript #node.js #amazon-web-services #express #amazon-s3
#javascript #node.js #amazon-веб-сервисы #экспресс #amazon-s3
Вопрос:
Я пытаюсь создать конечную точку в NodeJS / Express для загрузки содержимого из моей корзины AWS S3.
Это работает хорошо, я могу загрузить файл на стороне клиента, но я также вижу предварительный просмотр потока на вкладке Сеть, что раздражает…
ВОПРОС
Мне интересно, правильно ли то, что я делаю, и является ли это хорошей практикой. Также хотелось бы знать, нормально ли видеть выходной поток на вкладке Сеть.
Как мне правильно отправить файл из S3 в мое клиентское приложение с помощью NodeJS / Express?
Я почти уверен, что запросы других веб-сайтов не позволяют просматривать содержимое с помощью: «Не удается загрузить данные ответа«.
Это то, что я делаю в своем приложении NodeJS, чтобы получить файл потока из AWS S3:
download(fileId) {
const fileObjectStream = app.s3
.getObject({
Key: fileId
})
.createReadStream();
this.res.set("Content-Type", "application/octet-stream");
this.res.set(
"Content-Disposition",
'attachment; filename="' fileId '"'
);
fileObjectStream.pipe(this.res);
}
И на стороне клиента я вижу это:
Комментарии:
1. Я предполагаю, что другой вариант — заставить nodejs создать подписанный URL-адрес и вместо этого отправить его клиенту. Затем клиент может использовать этот подписанный URL-адрес для доступа к содержимому S3
Ответ №1:
Я думаю, что проблема связана с заголовком :
//this line will set proper header for file and make it downloadable in client's browser
res.attachment(key);
// this will execute download
s3.getObject(bucketParams)
.createReadStream()
.pipe(res);
Итак, код должен быть таким (это то, что я делаю в своем файле обработки проекта как res.attachment или res.json в случае ошибки, чтобы клиент мог отобразить ошибку конечному пользователю) :
router.route("/downloadFile").get((req, res) => {
const query = req.query; //param from client
const key = query.key;//param from client
const bucketName = query.bucket//param from client
var bucketParams = {
Bucket: bucketName,
Key: key
};
//I assume you are using AWS SDK
s3 = new AWS.S3({ apiVersion: "2006-03-01" });
s3.getObject(bucketParams, function(err, data) {
if (err) {
// cannot get file, err = AWS error response,
// return json to client
return res.json({
success: false,
error: err
});
} else {
res.attachment(key); //sets correct header (fixes your issue )
//if all is fine, bucket and file exist, it will return file to client
s3.getObject(bucketParams)
.createReadStream()
.pipe(res);
}
});
});
Комментарии:
1. Как это запускает загрузку на стороне клиента?
2. Ну, на стороне клиента правильный заголовок — это то, что запускает файл. В обычном HTTP-ответе заголовок ответа на размещение содержимого представляет собой заголовок, указывающий, ожидается ли, что содержимое будет отображаться встроенным в браузере, то есть как веб-страница или как часть веб-страницы, или как вложение, которое загружается и сохраняется локально. Например, расположение содержимого: вложение; filename =»whateverIfFileName.jpg » отправит браузеру указание на загрузку файла…. В моем коде выше res.attachment (ключ) — это то, что устанавливает правильный заголовок файла, чтобы файл можно было загрузить браузером. Я надеюсь, что это поможет.