নোড.জেএস, এক্সপ্রেস এবং মঙ্গুজ ব্যবহার করে চিত্র আপলোড করা হচ্ছে


102

বছরের পর বছরগুলিতে জিনিসগুলি পরিবর্তিত হওয়ায় দয়া করে নতুন উত্তরগুলিতে আরও যুগোপযোগী তথ্য বিবেচনা করুন!

যেহেতু অনেকগুলি নতুন নোড.জে গ্রন্থাগারগুলি দ্রুত অপ্রচলিত হিসাবে রেন্ডার করা হচ্ছে এবং তুলনামূলকভাবে কয়েকটি উদাহরণ রয়েছে যা ব্যবহার করে ছবি আপলোড করার বিষয়ে আমি জিজ্ঞাসা করতে চাই:

  • নোড.জেএস (v0.4.1)
  • এক্সপ্রেস (1.0.7)
  • মঙ্গুজ (২.১.০)

অন্যরা কীভাবে এটি করেছে?

আমি খুঁজে পেয়েছি: নোড-অজানা , তবে আমি সাধারণভাবে চিত্র আপলোড করতে নতুন তাই আমি সাধারণ জিনিস এবং নোড.জেএস এবং এক্সপ্রেস ব্যবহার করে এর পদ্ধতি শিখতে চাই।


12
আপডেট এক্সপ্রেসের নতুন সংস্করণগুলিতে এই কার্যকারিতাটি অন্তর্নির্মিত রয়েছে, বিবেচনা করুন 'কানেক্ট-
ফর্ম'

4
2015 টিএল; আপনার সার্ভারে মাল্টিপার্ট / ফর্ম অনুরোধগুলি প্রেরণ করুন এবং মডিটারের সাথে পার্স করুন যেহেতু বডি পার্সার আর ফাইলগুলি পার্স করে না। npm install multer --saveএবং তারপর আপনার অ্যাপে আপনি অ্যাক্সেস করতে পারেন req.files.your_file_param_nameএবং হয় সঙ্গে S3 সংরক্ষণ aws-sdkবাfs.writeFile(...)
ব্যবহারকারী

উত্তর:


74

আমি আমার নিজের প্রশ্নের উত্তর প্রথমবার দেব। সোজা উত্স থেকে আমি একটি উদাহরণ পেয়েছি। দরিদ্র প্রবণতা ক্ষমা করুন। অনুলিপি এবং আটকানোর সময় কীভাবে সঠিকভাবে ইনডেন্ট করা যায় তা আমি নিশ্চিত ছিলাম না। কোডটি সরাসরি গিটহাবের এক্সপ্রেস multipart/form-dataউদাহরণ থেকে আসে ।

// Expose modules in ./support for demo purposes
require.paths.unshift(__dirname + '/../../support');

/**
 * Module dependencies.
 */

var express = require('../../lib/express')
  , form = require('connect-form');

var app = express.createServer(
  // connect-form (http://github.com/visionmedia/connect-form)
  // middleware uses the formidable middleware to parse urlencoded
  // and multipart form data
  form({ keepExtensions: true })
);

app.get('/', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Image: <input type="file" name="image" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});

app.post('/', function(req, res, next){

  // connect-form adds the req.form object
  // we can (optionally) define onComplete, passing
  // the exception (if any) fields parsed, and files parsed
  req.form.complete(function(err, fields, files){
    if (err) {
      next(err);
    } else {
      console.log('\nuploaded %s to %s'
        ,  files.image.filename
        , files.image.path);
      res.redirect('back');
    }
  });

  // We can add listeners for several form
  // events such as "progress"
  req.form.on('progress', function(bytesReceived, bytesExpected){
    var percent = (bytesReceived / bytesExpected * 100) | 0;
    process.stdout.write('Uploading: %' + percent + '\r');
  });
});

app.listen(3000);
console.log('Express app started on port 3000');

3
হ্যাঁ তবে আপনি ফাইলটি কীভাবে সংরক্ষণ করবেন?
নিক রেটাল্যাক

1
@ নিকরেটাল্যাক সংরক্ষণ করা ফাইল ফাইলগুলিতে সংরক্ষিত আছে imaআইমেজ.প্যাথ
রবিন ডেকেট

@ রবিন-ডেকেট, আপনি ফাইলনাম এবং পথটি আগেই কীভাবে নির্দিষ্ট করেছেন?
লুক

4
@ লুক: আপনি করবেন না, এটি একটি অস্থায়ী ডিরেক্টরিতে সংরক্ষণ করা হয়েছে যা থেকে আপনি এটি অন্যত্র সরিয়ে নিয়েছেন।
kevmo314

1
আপনি কীভাবে এক্সপ্রেটেড আপলোড ডিরেক্টরিটি কনফিগার করেন: // দ্রষ্টব্য: সাবমডিউলগুলিতে সমস্যা এড়াতে আপলোড ডিরেক্টরিটিতে একটি নিখুঁত পাথ ব্যবহার করুন! // অ্যাপ.ইউজ (এক্সপ্রেস.ওডি পার্সার ({আপলোডডির: আপলোডডির}));
রিসাদিনহা

47

যেহেতু আপনি এক্সপ্রেস ব্যবহার করছেন, কেবল বডি পার্সার যুক্ত করুন:

app.use(express.bodyParser());

তারপরে আপনার রুটটিতে স্বয়ংক্রিয়ভাবে আপলোড করা ফাইলগুলিতে রেকি.ফাইলে অ্যাক্সেস রয়েছে:

app.post('/todo/create', function (req, res) {
    // TODO: move and rename the file using req.files.path & .name)
    res.send(console.dir(req.files));  // DEBUG: display available fields
});

আপনি যদি ইনপুট নিয়ন্ত্রণটিকে "টুডু" এর মতো নাম দেন (জেডে):

form(action="/todo/create", method="POST", enctype="multipart/form-data")
    input(type='file', name='todo')
    button(type='submit') New

তারপরে আপলোড করা ফাইলটি আপনি 'ফাইলস.টোডো'-তে পাথ এবং আসল ফাইলের নামটি পেয়ে যাওয়ার সময়ের মধ্যে প্রস্তুত থাকে:

  • req.files.todo.path, এবং
  • req.files.todo.name

অন্যান্য দরকারী req.files বৈশিষ্ট্য:

  • আকার (বাইটে)
  • প্রকার (যেমন, 'চিত্র / পিএনজি')
  • lastModifiedate
  • _witterStream.encoding (যেমন, 'বাইনারি')

আমি কখনই এটি সেভাবে উল্লেখ করেছি শুনেছি এবং আমি এগিয়ে যাব এবং বলব যে এই ছেলেরা ভাল বিকাশকারীকে জানে mo
srquinn

bodyParserএটি অনিরাপদ, কমপক্ষে এটি অনুসারে: andrewkelley.me/post/do-not-use-bodyparser-with-express-js.htmlজন জে এর উত্তর আমার পক্ষে কাজ করেছিল।
ম্যাট ব্রাউন 20

"অনিরাপদ" দ্বারা, এর অর্থ কেবলমাত্র টেম্প ফাইল তৈরি করা হয়েছে, যাতে কোনও "আক্রমণ" সম্ভবত টেম্পের ফাইলগুলির সাথে সার্ভারের ডিস্কের স্থানটি পূরণ করতে পারে। এটি সুরক্ষা গর্ত নয় বলে এটি আরও দৃ rob়তার সমস্যা।
ব্রেন্ট ফাউস্ট

19

আপনি আপনার মূল অ্যাপ্লিকেশন ফাইলে একটি কনফিগারেশন ব্লকে কানেক্ট বডি পার্সার মিডলওয়্যার কনফিগার করতে পারেন:

    /** Form Handling */
    app.use(express.bodyParser({
        uploadDir: '/tmp/uploads',
        keepExtensions: true
    }))
    app.use(express.limit('5mb'));

আমি মনে করি আপলোডগুলি হ্যান্ডেল করার জন্য এটি সর্বোত্তম উপায়। ফাইলটি অন্য কোনও জায়গায় অনুলিপি না করে কেবল মুছতে চাইলে ফাইলটি রাখুন। ধন্যবাদ।
পূর্ব সন্ন্যাসী

2
@ আকাশপ্রভুদেসাই হ্যাঁ এবং না। বলুন আপনার কাছে একটি ফটো আপলোড / ক্রপ সরঞ্জাম রয়েছে। যদি আপনি ব্যবহারকারীকে আপনার সর্বজনীন ফোল্ডারে সরাসরি আপলোড করার অনুমতি প্রদান করেন তবে আপনার একটি গুরুতর সুরক্ষা ত্রুটি রয়েছে। এই ক্ষেত্রে, কোনও টিএমপি ফোল্ডারে আপলোড করা এবং তারপরে ফাইলটি নিশ্চিত হওয়ার পরে আপনার সর্বজনীন ফোল্ডারে স্থানান্তরিত করা সেরা ট্রোজান নয়।
srquinn

আর সমর্থিত বলে মনে হচ্ছে না। দেখতে সুন্দর সমাধানের মতো লাগছিল।
জ্বলুন

14

দেখুন, আপনি যা করতে পারেন তার মধ্যে সবচেয়ে ভাল জিনিসটি কেবলমাত্র ডিস্কে চিত্রটি আপলোড করা এবং মঙ্গোডিবিতে URL টি সংরক্ষণ করা। আপনি যখন আবার চিত্রটি পুনরুদ্ধার করবেন তখন বিশ্রাম করুন। কেবল ইউআরএল নির্দিষ্ট করুন, এবং আপনি একটি চিত্র পাবেন। আপলোডের জন্য কোডটি নিম্নরূপ।

app.post('/upload', function(req, res) {
    // Get the temporary location of the file
    var tmp_path = req.files.thumbnail.path;
    // Set where the file should actually exists - in this case it is in the "images" directory.
    target_path = '/tmp/' + req.files.thumbnail.name;
    // Move the file from the temporary location to the intended location
    fs.rename(tmp_path, target_path, function(err) {
        if (err)
            throw err;
        // Delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files.
        fs.unlink(tmp_path, function() {
            if (err)
                throw err;
            //
        });
    });
});

এখন আপনার মঙ্গোডিবি ডাটাবেসে লক্ষ্যের পথটি সংরক্ষণ করুন।

আবার চিত্রটি পুনরুদ্ধার করার সময়, কেবল মঙ্গোডিবি ডাটাবেস থেকে URL টি বের করুন এবং এই পদ্ধতিতে এটি ব্যবহার করুন।

fs.readFile(target_path, "binary", function(error, file) {
    if(error) {
        res.writeHead(500, {"Content-Type": "text/plain"});
        res.write(error + "\n");
        res.end();
    }
    else {
        res.writeHead(200, {"Content-Type": "image/png"});
        res.write(file, "binary");
    }
});

9

এই কোডটি ব্যবহার করে দেখুন t এটি সাহায্য করবে।

app.get('/photos/new', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Data: <input type="filename" name="filename" /></p>'
    + '<p>file: <input type="file" name="file" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});


 app.post('/photos/new', function(req, res) {
  req.form.complete(function(err, fields, files) {
    if(err) {
      next(err);
    } else {
      ins = fs.createReadStream(files.photo.path);
      ous = fs.createWriteStream(__dirname + '/directory were u want to store image/' + files.photo.filename);
      util.pump(ins, ous, function(err) {
        if(err) {
          next(err);
        } else {
          res.redirect('/photos');
        }
      });
      //console.log('\nUploaded %s to %s', files.photo.filename, files.photo.path);
      //res.send('Uploaded ' + files.photo.filename + ' to ' + files.photo.path);
    }
  });
});

if (!module.parent) {
  app.listen(8000);
  console.log("Express server listening on port %d, log on to http://127.0.0.1:8000", app.address().port);
}

util.pump(ins, ous)অবচয় করা হয়, এটি ins.pipe(ous);এখন দিয়ে করা যেতে পারে । তবে এটি কি পুরানো লোকেশনের চিত্র ফাইলটি সরিয়ে দেবে?
এমিয়েল ভ্যান্ডেনবাশ্চে

8

আপনি যেখানে ফাইলটি সংরক্ষণ করে সেখানে কোনও পথ নির্ধারণ করতে নিম্নলিখিত ব্যবহার করতে পারেন।

req.form.uploadDir = "<path>";

5

আমি এক্সপ্রেস এবং মুলটার ব্যবহার করে এমন একটি উদাহরণ তৈরি করেছি। এটি খুব সহজ এবং সমস্ত সংযোগ সতর্কতা এড়ানো হয়

এটি কারও সাহায্য করতে পারে।


1
এর জন্য ধন্যবাদ. এটি সম্পূর্ণরূপে আপ টু ডেট উদাহরণগুলি খুঁজে পাওয়া শক্ত যেগুলি ব্যবহার করে না bodyParser(যা অনিরাপদ, দেখুন andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html )
ম্যাট ব্রাউন

2

আবার যদি আপনি বডি পার্সার ব্যবহার না করতে চান তবে নিম্নলিখিতগুলি কাজ করে:

var express = require('express');
var http = require('http');
var app = express();

app.use(express.static('./public'));


app.configure(function(){
    app.use(express.methodOverride());
    app.use(express.multipart({
        uploadDir: './uploads',
        keepExtensions: true
    }));
});


app.use(app.router);

app.get('/upload', function(req, res){
    // Render page with upload form
    res.render('upload');
});

app.post('/upload', function(req, res){
    // Returns json of uploaded file
    res.json(req.files);
});

http.createServer(app).listen(3000, function() {
    console.log('App started');
});

2

এক্সপ্রেস 3.0.০ এর জন্য, আপনি যদি শক্তিশালী ইভেন্টগুলি ব্যবহার করতে চান তবে আপনাকে অবশ্যই মাল্টিপার্ট মিডলওয়্যারটি সরিয়ে ফেলতে হবে, যাতে আপনি এটির নতুন উদাহরণটি তৈরি করতে পারেন।

এটা করতে:

app.use(express.bodyParser());

হিসাবে লেখা যেতে পারে:

app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart()); // Remove this line

এবং এখন ফর্ম অবজেক্ট তৈরি করুন:

exports.upload = function(req, res) {
    var form = new formidable.IncomingForm;
    form.keepExtensions = true;
    form.uploadDir = 'tmp/';

    form.parse(req, function(err, fields, files){
        if (err) return res.end('You found error');
        // Do something with files.image etc
        console.log(files.image);
    });

    form.on('progress', function(bytesReceived, bytesExpected) {
        console.log(bytesReceived + ' ' + bytesExpected);
    });

    form.on('error', function(err) {
        res.writeHead(400, {'content-type': 'text/plain'}); // 400: Bad Request
        res.end('error:\n\n'+util.inspect(err));
    });
    res.end('Done');
    return;
};

আমি এটিকে আমার ব্লগে পোস্ট করেছি, আপলোডের সময় এক্সপ্রেস in.০ তে শক্তিশালী ফর্ম অবজেক্ট পেয়েছি ।


আপনার পরামর্শ মিসেলিডিং, বডি পার্সার মূলত ফর্মটি পার্স করে। এবং শক্তিশালী কনফিগার ভেরিয়েবল গ্রহণ করে।
মারিয়াস

1
@ টিমক্স্লে এটির উদাহরণ
রিস্টো নভিক

1

আমি জানি যে সুনির্দিষ্ট সংস্করণগুলির সাথে সম্পর্কিত মূল প্রশ্নটি, তবে এটি "সর্বশেষ" - @ জন অ্যালেনের পোস্টকেও উল্লেখ করেছে এক্সপ্রেসজেস ​​বডি পার্সার এবং সংযোগ-ফর্মের কারণে আর প্রাসঙ্গিক নয়

এটি অন্তর্নির্মিত বডি পার্সার () ব্যবহার করা সহজ হিসাবে দেখায়:

 /**
 * Module dependencies.
 */

var express = require('express')

var app = express()
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/home/svn/rest-api/uploaded' }))

app.get('/', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Image: <input type="file" name="image" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});

app.post('/', function(req, res, next){

    res.send('Uploaded: ' + req.files.image.name)
    return next()

});

app.listen(3000);
console.log('Express app started on port 3000');

0

একাধিক আপলোড ফাইল করার জন্য আমার পদ্ধতি আছে:

নোডেজ:

router.post('/upload', function(req , res) {

var multiparty = require('multiparty');
var form = new multiparty.Form();
var fs = require('fs');

form.parse(req, function(err, fields, files) {  
    var imgArray = files.imatges;


    for (var i = 0; i < imgArray.length; i++) {
        var newPath = './public/uploads/'+fields.imgName+'/';
        var singleImg = imgArray[i];
        newPath+= singleImg.originalFilename;
        readAndWriteFile(singleImg, newPath);           
    }
    res.send("File uploaded to: " + newPath);

});

function readAndWriteFile(singleImg, newPath) {

        fs.readFile(singleImg.path , function(err,data) {
            fs.writeFile(newPath,data, function(err) {
                if (err) console.log('ERRRRRR!! :'+err);
                console.log('Fitxer: '+singleImg.originalFilename +' - '+ newPath);
            })
        })
}
})

আপনার ফর্মটি এনকটাইপ = "বহুগুণ / ফর্ম-ডেটা" রয়েছে তা নিশ্চিত করুন

আমি আশা করি এটি আপনাকে একটি হাত দেয়;)


0

এক্সপ্রেসের পরবর্তী সংস্করণগুলিতে বডি পার্সারের মাধ্যমে সুপারিশ করা মজাদার প্যাকেজ ব্যবহার করে আপনার চিত্রগুলি আপলোড করার একটি উপায় এখানে রয়েছে। এর মধ্যে ফ্লাইতে আপনার চিত্রগুলি পুনরায় আকার দেওয়ার ক্ষমতাও অন্তর্ভুক্ত:

আমার ওয়েবসাইট থেকে: নোড.জেএস এবং এক্সপ্রেস সহ চিত্রগুলি আপলোড এবং পুনরায় আকার দিন (ফ্লাইতে)

এখানে সংক্ষেপ:

var express = require("express"),
app = express(),
formidable = require('formidable'),
util = require('util')
fs   = require('fs-extra'),
qt   = require('quickthumb');

// Use quickthumb
app.use(qt.static(__dirname + '/'));

app.post('/upload', function (req, res){
  var form = new formidable.IncomingForm();
  form.parse(req, function(err, fields, files) {
    res.writeHead(200, {'content-type': 'text/plain'});
    res.write('received upload:\n\n');
    res.end(util.inspect({fields: fields, files: files}));
  });

  form.on('end', function(fields, files) {
    /* Temporary location of our uploaded file */
    var temp_path = this.openedFiles[0].path;
    /* The file name of the uploaded file */
    var file_name = this.openedFiles[0].name;
    /* Location where we want to copy the uploaded file */
    var new_location = 'uploads/';

    fs.copy(temp_path, new_location + file_name, function(err) {  
      if (err) {
        console.error(err);
      } else {
        console.log("success!")
      }
    });
  });
});

// Show the upload form 
app.get('/', function (req, res){
  res.writeHead(200, {'Content-Type': 'text/html' });
  /* Display the file upload form. */
  form = '<form action="/upload" enctype="multipart/form-data" method="post">'+ '<input name="title" type="text" />
  '+ '<input multiple="multiple" name="upload" type="file" />
  '+ '<input type="submit" value="Upload" />'+ '</form>';
  res.end(form); 
}); 
app.listen(8080);

দ্রষ্টব্য: দ্রুত থাম্ব পুনরায় আকার দেওয়ার জন্য এর জন্য চিত্র ম্যাজিকের প্রয়োজন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.