Рубрики
Без рубрики

Загрузить файлы до s3 в node.js

Мое волнение по реализации загрузки файлов не заняло слишком много времени, чтобы превратиться в борьбу, а затем страх, но F … с меткой узла, JavaScript, AWS.

Мое волнение по реализации загрузки файлов не заняло слишком много времени, чтобы превратиться в борьбу, а затем страх, но, наконец, победоносный толчок к финишу. Это моя скромная попытка помочь вам пропустить линию и прыгнуть прямо на третий этап.

Если вы тот, кто здесь для конкретной информации, вы можете пропустить любую из следующих ниже:

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”