2017-08-07 1 views
1

Ich habe diese Express-Route mit multer Datei-Upload. Wenn das Hochladen abgeschlossen ist, möchte ich das Bild zu base64 kodieren und mit Antwort senden.Node.js: Multer mit Versprechen hochladen?

Wenn ich es jedoch so mache, versucht der Code, die base64-Codierung auszuführen, bevor die Datei im Ordner erstellt wird.

bearbeiten: hinzugefügt Speicher & Upload-Funktionen

const storage = multer.diskStorage({ 
    destination: (req, file, callback) => { 
     if (!fs.existsSync('./uploads')) { 
      fs.mkdirSync('./uploads'); 
     } 
     let path = './uploads'; 
     callback(null, path); 
    }, 
    filename(req, file, cb) { 
     let fileExt = file.originalname.substring(file.originalname.lastIndexOf('.')).toLowerCase(); 
     if (!imageFilter(fileExt)) { 
      return false; 
     } else { 
      cb(null, file.originalname); 
     } 
    }, 
    onError: function (err, next) { 
     console.log('error', err); 
     next(err); 
    }, 
}); 

const upload = multer({ 
    storage, 
    limits: { 
     fileSize: 1000 * 1000 * 2 // 2 MB 
    } 
}).single('file'); 

router.post('/upload', function (req, res) { 
    var directory = 'uploads'; 
    fs.readdir(directory, (err, files) => { 
     if (err) throw err; 
     for (var file of files) { 
      fs.unlink(path.join(directory, file), err => { 
       if (err) throw err; 
      }); 
     } 
    }); 
    upload(req, res, function (err) { 
     if (err) { 
      return res.status(404).json({ 
       success: false, 
       message: 'File is too large. (Max 2MB)' 
      }); 
     } 

     var file = req.file; 
     var base64str = base64_encode('./uploads/' + file.originalname); 

     return res.status(200).json({ 
      success: true, 
      url: 'http://' + ip.address() + ':' + constants.PORT + '/api/uploads/' + file.originalname, 
      image: 'data:image/png;base64,' + base64str 
     }); 
    }); 
}); 

Was wäre der klügste Weg, um die richtige Reihenfolge der Operationen zu erreichen. Möglicherweise versprechen oder async/erwarten?

+0

Könnten Sie bitte die 'upload' Funktionscode hinzufügen? –

+1

Oh ja, tut mir leid. –

+0

Welche Art von Speicher haben Sie implementiert? – Tolsee

Antwort

2

Diese Lösung für mich gearbeitet:

Knoten v8.4.0 ist erforderlich für dieses

//app.js 
const fs = require('fs'); 
const express = require('express'); 
const cors = require('cors'); 
const bodyParser = require('body-parser'); 
const app = express(); 

app.use(cors({credentials: true, origin: 'http://localhost:4200'})); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: true })); 

const Uploader = require('./Uploader.js'); 
const uploader = new Uploader(); 

app.post('/upload', uploader.startUpload); 


//Uploader.js 

const util = require("util"); 
const crypto = require("crypto"); 
const multer = require('multer'); 

class Uploader { 

    constructor() { 
     const storageOptions = multer.diskStorage({ 
      destination: function(req, file, cb) { 
       cb(null, __dirname + '/uploads/') 
      }, 
      filename: function(req, file, cb) { 
       crypto.pseudoRandomBytes(16, function(err, raw) { 
        cb(null, raw.toString('hex') + Date.now() + '.' + file.originalname); 
       }); 
      } 
     }); 

     this.upload = multer({ storage: storageOptions }); 
    } 

    async startUpload(req, res) { 
     let filename; 

     try { 
      const upload = util.promisify(this.upload.any()); 

      await upload(req, res); 

      filename = req.files[0].filename; 
     } catch (e) { 
      //Handle your exception here 
     } 

     return res.json({fileUploaded: filename}); 
    } 
} 
Verwandte Themen