Мое волнение по реализации загрузки файлов не заняло слишком много времени, чтобы превратиться в борьбу, а затем страх, но, наконец, победоносный толчок к финишу. Это моя скромная попытка помочь вам пропустить линию и прыгнуть прямо на третий этап.
Если вы тот, кто здесь для конкретной информации, вы можете пропустить любую из следующих ниже:
1. Загрузить файл в целом с помощью Multer
2. Загрузите кусочки с автобусом
Давайте начнем с того, что выгружаем загрузчик для vue.js
Во -первых, давайте позволим нашему пользователю загрузить файл с помощью vue.js, чтобы он мог достичь нашего API.
Для этого мы начинаем с тега:
Вышеупомянутое Вход Тег позволяет пользователю загружать один файл. После выбора файла Onchange Метод вызывается с помощью данных файла.
Onchange Метод выглядит ниже:
function onChange() {
const data = new FormData();
for (const [key, value] of Object.entries(this.options)) {
data.append(key, value);
}
const file = this.$refs.inputFile.files[0];
data.append('file', fileToUpload, file.name);
const {data: res} = await axios.post(API`/files`, data);
}
При этом наш фронт-конце хорошо, чтобы идти, и теперь мы готовы отправить наш файл на S3.
Multer-S3 экономит день
Этот подход позволит вам загрузить файл непосредственно на AWS S3, не делая ничего среднего.
Когда использовать этот подход:
- Вы хотите подключить свои данные в место в ведре S3, не изменяя или доступа к байтам файлов. Короче говоря, этот метод будет поддерживать весь ваш файл без необходимости ничего делать.
Вот как выглядит основной скелет. Он содержит ваше объявление Multer и конечную точку API.
const upload = multer({});
router.post('/file', upload.single('file'), async (req, res) => {
});
Начнем с указания загрузить Метод:
const multer = require('multer');
const multerS3 = require('multer-s3');
const upload = multer({
storage: multerS3({
s3, // instance of your S3 bucket
contentDisposition: 'attachment',
contentType: multerS3.AUTO_CONTENT_TYPE,
bucket(req, file, callb) {
// logic to dynamically select bucket
// or a simple `bucket: __bucket-name__,`
callb(null, '_my_bucket_');
},
metadata(req, file, cb) {
cb(null, {
'X-Content-Type-Options': 'nosniff',
'Content-Security-Policy': 'default-src none; sandbox',
'X-Content-Security-Policy': 'default-src none; sandbox',
});
},
async key(req, file, abCallback) {
try {
// logic to dynamically select key or destination
abCallback(null, ' _dest/key_');
} catch (err) {
abCallback(err);
}
},
}),
limits: {}, // object with custom limits like file size,
fileFilter: filterFiles, // method returns true or false after filtering the file
});
Затем мы передаем его промежуточным программным обеспечением в нашу конечную точку API.
router.post('/file', upload.single('file'), async (req, res) => {
// you can access all the FormData variables here using req.file._var_name
});
Это оно! Все данные, относящиеся к вашей загрузке S3, будут доступны в рамках req.file переменная.
При этом мы успешно загрузили ваш файл в S3, простой способ.
Когда спас день с автобусом
Затем наступает ситуация, когда вы хотите получить доступ к байтам, которые вы приводите в свое ведро S3, до того, как произойдет фактическая загрузка. Возможно, вы захотите сжать их, распаковать их, проверить вирус или выполнить любые другие бесконечные требования. Я решил использовать Busboy Здесь это проверенная, проверенная и простая в использовании библиотеку. Другие варианты, на которые вы можете получить, – это библиотеки, такие как Грозное или Multiparty Анкет
Когда использовать этот подход:
- Вы хотите получить доступ к кускам файлов, изменить их или использовать их, прежде чем поднять их в свое ведро S3.
Вот как выглядит основная структура. Опять же, содержит основное определение вместе с нашей обычной конечной точкой API.
const busboyUpload = (req) => {};
router.post('/file', async (req, res) => {
});
Итак, давайте погрузимся прямо в. Автобус называется методом из нашего API с Запрос как его параметр, как определено ниже.
router.post('/file', async (req, res) => {
try {
const uploadedFileData = await busboyUpload(req);
req.file = uploadedFileData;
res.sendStatus(200);
} catch (err) {
res.sendStatus(500);
}
}
Наш загрузчик автобуса будет настроен простым и простым образом.
- Мы начнем с возвращения обещания и инициируем наш экземпляр Busboy вместе с основной структурой.
const busboyUpload = (req) => new Promise((resolve, reject) => {
const busboy = new Busboy({});
});
- Затем мы определяем массив, который поможет нам проверить, завершилась ли загрузка или нет. Это позволит нам вернуть подходящий ответ.
const fileUploadPromise = [];
- На этом следующем шаге мы будем работать над фактическим файлом. Мы определяем слушателя, который выполняется, когда встречается файл.
busboy.on('file', async (fieldname, file, filename, encoding, mimetype) => {
// check for conditions and set your logic here
// s3Bucket = '_Bucket_';
// s3Key = '_Key_';
// check file size and file type here
});
- Внутри
OnfileСлушатель выше, мы загрузим в S3, используяЧитатьиПереходручей. Как будет определено наши потоки и загрузка S3:
const { Readable, PassThrough } = require('stream');
const s3 = require('@/utils/awsConnect').getS3();
const passToS3 = new PassThrough();
const fileReadStream = new Readable({
read(size) {
if (!size) this.push(null);
else this.push();
},
});
fileUploadPromise.push(new Promise((res, rej) => {
s3.upload({
Bucket: bucket,
Key: key,
Body: passToS3,
contentDisposition: 'attachment',
}, (err, data) => {
if (err) {
rej();
} else {
res({ ...data, originalname: filename, mimetype });
}
});
}));
fileReadStream.pipe(passToS3);
Что здесь происходит: Мы создаем Читать поток, передайте его Переход и после создания Пройти через Мы подчиняем его функции загрузки S3. Прежде чем начать загрузку, мы выдвигаем его как обещание к FileUploadPromise массив, который мы создали ранее.
- Чтобы начать загрузку файла, мы определяем следующие слушатели внутри наших
Onfileслушатель. На событии Chunk/Data мы подталкиваем то же самое кЧитатьПоток, который, в свою очередь, подтолкнет его к нашему S3.
file.on('data', async (data) => {
fileReadStream.push(Buffer.from(nextChunk));
});
file.on('end', () => {
fileReadStream.push(null);
});
- Наконец, мы определяем наш
OnfinishСоблюдение, просьба о просьбе на автобус, сядьте и расслабьтесь. Вы заметите, мы ждемFileUploadPromiseЧтобы завершить здесь, прежде чем мы отправим ответ обратно.
busboy.on('finish', () => {
Promise.all(fileUploadPromise).then((data) => {
resolve(data[0]);
})
.catch((err) => {
reject(err);
});
});
req.pipe(busboy);
В конце концов, это то, как ваш Busboyupload Структура должна выглядеть как.
const busboyUpload = (req) => new Promise((resolve, reject) => {
const busboy = new Busboy({ });
busboy.on('file', async (fieldname, file, filename, encoding, mimetype) => {
fileReadStream.pipe(passToS3);
file.on('data', async (data) => {
});
file.on('end', () => {
});
});
busboy.on('finish', () => {
});
req.pipe(busboy);
});
При этом вы хорошо настроены на загрузку файлов в S3 правильно.
Или вы можете даже использовать созданный я пакет NPM: https://www.npmjs.com/package/@losttracker/s3-uploader
Спасибо за чтение!:)
Оригинал: “https://dev.to/yuvraj2112/upload-files-to-s3-in-node-js-3hfp”