Как отправить несколько типов кодирования с помощью метода post и nodejs? - PullRequest
2 голосов
/ 07 марта 2020

Я пытаюсь отправить текстовое имя и описание вместе с видео, но могу отправить только видео или текст, но не оба.

Это код .e js для файл поста:

<!DOCTYPE html>
<html>
<body>
    <form action="/uploadvideo" enctype="multipart/form-data" method="POST">
        <input type="text" name="name" placeholder="Name" required/>
        <input type="text" name="description" placeholder="Description" required/>
        <input type="file" name="video" accept=".mp4" required/>
        <input type="submit" value="Upload"/>
    </form>
</body>
</html>

Это код nodejs для метода поста:

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        const directories = getDirectories('views/videos/')
        const nextNumber = parseInt(directories[directories.length - 1])
        if (nextNumber === NaN)
        {
            cb(new Error('Cannot save file, NaN'), null)
        }
        else
        {
            cb(null, 'views/videos/' + nextNumber)
        }
    },
    filename: function (req, file, cb) {
        cb(null, 'video.mp4')
    }
})

var upload = multer({storage: storage})

app.post('/uploadvideo', (req, res, next) => {
    const directories = getDirectories('views/videos/')
    const nextNumber = parseInt(directories[directories.length - 1]) + 1
    if (!fs.existsSync('views/videos/' + nextNumber))
    {
        fs.mkdirSync('views/videos/' + nextNumber)
    }
    fs.writeFileSync('views/videos/' + nextNumber + '/data.txt', req.body.name + '\n' + req.body.description + '\n')
    fs.writeFileSync('views/videos/' + nextNumber + '/video.mp4', 'error')
    return next()
}, upload.any('video'), (req, res, next) => {
    const directories = getDirectories('views/videos/')
    const nextNumber = parseInt(directories[directories.length - 1])
    if (fs.readFileSync('views/videos/' + nextNumber + '/video.mp4').toString() === 'error')
    {
        rimraf.sync('views/videos/' + nextNumber)
        res.render('error.ejs', {message: "Error uploading video"})
    }
    else
    {
        loadVideo(nextNumber)
        res.redirect('/video?video=' + nextNumber)
    }
})

Если я отправлю, установите для enctype только «multipart / form-data» видео отправлено, а текст не определен, но если я использую «application / x- www-form-urlencoded», отправляется только текст, а видео нет.

Можно ли как-то отправить оба? Заранее спасибо.

1 Ответ

0 голосов
/ 07 марта 2020

Сначала присоедините multer, он отделит req.file от req.body:

const fsPromises = require('fs').promises;
const path = require('path');
const pathToVideos = path.join(__dirname, 'views/videos/');

app.post(
  '/uploadvideo',
  upload.any('video'),
  async (req, res, next) => {
    const directories = getDirectories(pathToVideos);
    const nextNumber = parseInt(directories[directories.length - 1]) + 1;
    const newVideoFolder = pathToVideos + '/' + nextNumber;

    try {
      // checking if folder exists
      const exists = await fsPromises.access(newVideoFolder).then(() => true).catch(() => false);
      if (!exists) await fsPromises.mkdir(newVideoFolder); // need to create

      // writing to file info to data.txt
      await fsPromises.writeFile(
        path.join(newVideoFolder, 'data.txt'),
        req.body.name + '\n' + req.body.description + '\n'
      );

      // if file not exists throw error
      await fsPromises.access(
        path.join(newVideoFolder, 'video.mp4')
      );

      loadVideo(nextNumber);
      res.redirect('/video?video=' + nextNumber);
    } catch (error) {
      rimraf(newVideoFolder, () => {});
      console.error(error);
      res.render('error.ejs', {message: "Error uploading video"});
    }
  });

PS Используйте обещания с async / await (руководство: https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_promises_api)

примеры: https://www.codota.com/code/javascript/functions/fs/promises

...