webentwicklung-frage-antwort-db.com.de

Entpacke Zip in den Ordner Node via Express

Ich versuche ein Beispiel zu finden, wo ich eine Zip verschicken kann (wie per Postbote) und bekomme diese Zip in meinen Handler und unzip es ist so spezifizierter Ordner Ich habe nicht viele Beispiele zum Zippen gefunden using express Ich möchte es im Pfad web/app entpacken

Ich versuche etwas wie das Folgende, was für mich nicht funktioniert, die Zip-Datei ist nicht in den angegebenen Ordner entpackt, eine Idee, was ich falsch mache?

https://nodejs.org/api/zlib.html#zlib_zlib

var zlib = require('zlib');
var fs = require('fs');
const dir = path.join(__dirname, 'web/app/');

if (req.file.mimetype === 'application/Zip') {

    var unzip = zlib.createUnzip();

    var read = fs.createReadStream(req.file);
    var write = fs.createWriteStream(dir);
    //Transform stream which is unzipping the zipped file
    read.pipe(unzip).pipe(write);   
    console.log("unZipped Successfully");

}

Jedes Arbeitsbeispiel wird sehr hilfreich sein, oder wo kann ich ein Problem haben ...

während des Debuggens sehe ich, dass dies der Fall ist, wenn der Code fehlgeschlagen ist

var read = fs.createReadStream(req.file);

eine Idee warum?

Ich habe es auch mit versucht

var read = fs.createReadStream(req.file.body);

das Problem, dass ich den Fehler nicht sehe, Grund usw.

wenn ich es ändere

var read = fs.createReadStream(req.file.buffer);

das Programm wird nicht beendet und ich konnte es ausführen, bis der Logger console.log("unZipped Successfully"); aber nichts passiert ...

wenn es ein Beispiel mit https://www.npmjs.com/package/yauzl yauzl und multer in meinem Kontext gibt, wird es großartig sein

update - das ist die Postbotenanfrage

 enter image description here

9
user4445419

Zunächst unterstützt zlib das Extrahieren von Zip-Dateien nicht. 

Ich empfehle formidable für die Behandlung von Dateien, weil

  1. seine Schlacht getestet
  2. am häufigsten verwendet
  3. vermeidet das Schreiben von Plattenkennzeichencode wie das Lesen des Dateistreams von der Anforderung, das Speichern und das Behandeln von Fehlern
  4. einfach konfigurierbar

Voraussetzungen
Abhängigkeiten mit npm i -S extract-Zip formidable express oder yarn add extract-Zip formidable express installieren

Minimale Lösung für Ihr Problem mit formidable und extract-Zip

const express = require('express');
const fs = require('fs');
const extract = require('extract-Zip')
const formidable = require('formidable');
const path = require('path');
const uploadDir = path.join(__dirname, '/uploads/');
const extractDir = path.join(__dirname, '/app/');
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir);
}
if (!fs.existsSync(extractDir)) {
  fs.mkdirSync(extractDir);
}

const server = express();

const uploadMedia = (req, res, next) => {
  const form = new formidable.IncomingForm();
  // file size limit 100MB. change according to your needs
  form.maxFileSize = 100 * 1024 * 1024;
  form.keepExtensions = true;
  form.multiples = true;
  form.uploadDir = uploadDir;

  // collect all form files and fileds and pass to its callback
  form.parse(req, (err, fields, files) => {
    // when form parsing fails throw error
    if (err) return res.status(500).json({ error: err });

    if (Object.keys(files).length === 0) return res.status(400).json({ message: "no files uploaded" });

    // Iterate all uploaded files and get their path, extension, final extraction path
    const filesInfo = Object.keys(files).map((key) => {
      const file = files[key];
      const filePath = file.path;
      const fileExt = path.extname(file.name);
      const fileName = path.basename(file.name, fileExt);
      const destDir = path.join(extractDir, fileName);

      return { filePath, fileExt, destDir };
    });

    // Check whether uploaded files are Zip files
    const validFiles = filesInfo.every(({ fileExt }) => fileExt === '.Zip');

    // if uploaded files are not Zip files, return error
    if (!validFiles) return res.status(400).json({ message: "unsupported file type" });

    res.status(200).json({ uploaded: true });

    // iterate through each file path and extract them
    filesInfo.forEach(({filePath, destDir}) => {
      // create directory with timestamp to prevent overwrite same directory names
      extract(filePath, { dir: `${destDir}_${new Date().getTime()}` }, (err) => {
        if (err) console.error('extraction failed.');
      });
    });
  });

  // runs when new file detected in upload stream
  form.on('fileBegin', function (name, file) {
    // get the file base name `index.css.Zip` => `index.html`
    const fileName = path.basename(file.name, path.extname(file.name));
    const fileExt = path.extname(file.name);
    // create files with timestamp to prevent overwrite same file names
    file.path = path.join(uploadDir, `${fileName}_${new Date().getTime()}${fileExt}`);
  });
}

server.post('/upload', uploadMedia);

server.listen(3000, (err) => {
  if (err) throw err;
});

Diese Lösung funktioniert für das Hochladen einzelner oder mehrerer Dateien. Das einzige Problem bei dieser Lösung besteht darin, dass falsche Dateitypen in das uploaded-Verzeichnis hochgeladen werden, obwohl ein Serverfehler auftritt.

Zum Testen mit dem Postboten: postman image

2
REDDY PRASAD

Voraussetzungen :

  1. npm i express unzipper multiparty bluebird
  2. Erstellen Sie das app/web-Verzeichnis in Ihrem Projektstamm (oder Sie können die Erstellung automatisieren, wenn Sie möchten).
  3. Legen Sie alle diese Dateien in einem Verzeichnis ab.
  4. Knotenversion, die async/await unterstützt (7.6+, soweit ich weiß)

server.js :

const express = require('express');
const Promise = require('bluebird');
const fs = require('fs');
const writeFile = Promise.promisify(fs.writeFile);

const { parseRequest, getFile } = require('./multipart');
const { extractFiles } = require('./Zip')

const EXTRACT_DIR = 'web/app';

const app = express();

const uploadFile = async (req, res, next) => {
  try {
    const body = await parseRequest(req);
    const bodyFile = getFile(body, 'file');
    if (!/\.Zip$/.test(bodyFile.originalFilename)) {
      res.status(200).json({ notice: 'not a Zip archive, skipping' })
      return;
    }
    const archiveFiles = await extractFiles(bodyFile);

    await Promise.each(archiveFiles, async (file) => {
      await writeFile(EXTRACT_DIR + '/' + file.path, file.buffer);
    })
    res.status(200).end();
  } catch (e) {
    res.status(500).end();
  }
};

app.post('/files', uploadFile);

app.listen(3000, () => {
  console.log('App is listening on port 3000');
});

multipart.js

const Promise = require('bluebird');
const { Form } = require('multiparty');

function parseRequest (req, options) {
    return new Promise((resolve, reject) => {
        const form = new Form(options)
        form.parse(req, (err, fields, files) => {
            if (err) {
                return reject(err);
            }
            return resolve({ fields, files });
        });
    });
}

function getFile (body, field) {
    const bodyFile = body.files[field];
    const value = bodyFile ? bodyFile[0] : null;
    return value || null;
}

module.exports = {
    parseRequest,
    getFile,
};

Zip.js

const unzip = require('unzipper');
const fs = require('fs');

async function extractFiles (file) {
    const files = [];
    await fs.createReadStream(file.path).pipe(unzip.Parse()).on('entry', async entry => {
    // Cleanup system hidden files (or drop this code if not needed)
        if (
            entry.type !== 'File'
            || /^__MACOSX/.test(entry.path)
            || /.DS_Store/.test(entry.path)
        ) {
            entry.autodrain()
            return
        }
        const pathArr = entry.path.split('/');
        const path = entry.path;
        const buffer = await entry.buffer();
        files.Push({ buffer, path, originalFilename: pathArr[pathArr.length - 1] });
    }).promise();
    return files;
}

module.exports = {
    extractFiles,
};

Verwendungszweck :

  1. Starten Sie einen Server mit node server
  2. Senden Sie Ihre Datei im Feld file in der Anforderung (Schlüssel file im Postboten). Beispiel in curl curl -XPOST -F '[email protected]/ttrra-dsp-agency-api/banner.Zip' 'localhost:3000/files')

Nachteile :

  1. Nicht gepackte Dateien werden im Puffer gespeichert. Diese Methode funktioniert daher nicht gut und wird nicht für große Archive empfohlen.
2
coockoo

Ohne ein vollständiges Beispiel ist es schwer zu sagen, was das eigentliche Problem ist. Aber laut Express docs heißt es: 

In Express 4 ist req.files nicht mehr für das req-Objekt von .__ verfügbar. Standard. Um auf die hochgeladenen Dateien im Objekt req.files zuzugreifen, verwenden Sie Multipart-Handling-Middleware wie Busboy, Multer, beeindruckend, Multiparty, Connect-Multiparty oder Pez.

Wenn Sie also keine Middleware-Bibliothek für das Hochladen von Dateien verwenden, ist es schwierig, den Wert von req.file zu ermitteln. 

Ich bin auch etwas besorgt, dass Sie versuchen, eine ZIP-Datei mit zlib zu dekomprimieren, da die library nur gzip unterstützt.

Das zlib-Modul bietet eine Komprimierungsfunktion, die mithilfe von .__ implementiert wird. Gzip und Luft ablassen/aufblasen

Sie möchten nach req.file.mimetype === 'application/gzip' suchen

Hier einige Beiträge zum Entpacken von Zip-Dateien:

2
jjbskir