Мое волнение по реализации загрузки файлов не заняло слишком много времени, чтобы превратиться в борьбу, а затем страх, но, наконец, победоносный толчок к финишу. Это моя скромная попытка помочь вам пропустить линию и прыгнуть прямо на третий этап.
Если вы тот, кто здесь для конкретной информации, вы можете пропустить любую из следующих ниже:
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”