बेस 64 एन्कोडेड छवियों को वापस भेजने से बचें (एकाधिक छवियां + बड़ी फाइलें + बड़ी एन्कोडेड स्ट्रिंग्स =बहुत धीमी प्रदर्शन)। मैं एक माइक्रोसर्विस बनाने की अत्यधिक अनुशंसा करता हूं जो केवल छवि अपलोड और किसी अन्य छवि से संबंधित प्राप्त/पोस्ट/पुट/डिलीट अनुरोधों को संभालता है। इसे अपने मुख्य एप्लिकेशन से अलग करें।
उदाहरण के लिए:
- मैं इमेज बफर बनाने के लिए मल्टर का उपयोग करता हूं
- फिर छवि को सहेजने के लिए शार्प या fs का उपयोग करें (फ़ाइल प्रकार के आधार पर)
- फिर मैं अपने डीबी में सहेजे जाने के लिए अपने नियंत्रक को फ़ाइलपथ भेजता हूं
- फिर, जब फ्रंट-एंड एक्सेस करने का प्रयास करता है तो एक GET अनुरोध करता है:
http://localhost:4000/uploads/timestamp-randomstring-originalname.fileext
साधारण शब्दों में, मेरी माइक्रोसर्विस केवल छवियों के लिए सीडीएन की तरह काम करती है।
उदाहरण के लिए, एक उपयोगकर्ता http://localhost:4000/api/avatar/create
पर एक पोस्ट अनुरोध भेजता है कुछ फॉर्मडाटा के साथ:
यह पहले कुछ एक्सप्रेस मिडलवेयर से होकर गुजरता है:
libs/middlewares.js
...
app.use(cors({credentials: true, origin: "http://localhost:3000" })) // allows receiving of cookies from front-end
app.use(morgan(`tiny`)); // logging framework
app.use(multer({
limits: {
fileSize: 10240000,
files: 1,
fields: 1
},
fileFilter: (req, file, next) => {
if (!/\.(jpe?g|png|gif|bmp)$/i.test(file.originalname)) {
req.err = `That file extension is not accepted!`
next(null, false)
}
next(null, true);
}
}).single(`file`))
app.use(bodyParser.json()); // parses header requests (req.body)
app.use(bodyParser.urlencoded({ limit: `10mb`, extended: true })); // allows objects and arrays to be URL-encoded
...etc
फिर, avatars
को हिट करें मार्ग:
मार्ग/अवतार.js
app.post(`/api/avatar/create`, requireAuth, saveImage, create);
यह तब कुछ उपयोगकर्ता प्रमाणीकरण से गुजरता है, फिर मेरे saveImage
. के माध्यम से जाता है मिडलवेयर:
सेवाएं/saveImage.js
const createRandomString = require('../shared/helpers');
const fs = require("fs");
const sharp = require("sharp");
const randomString = createRandomString();
if (req.err || !req.file) {
return res.status(500).json({ err: req.err || `Unable to locate the requested file to be saved` })
next();
}
const filename = `${Date.now()}-${randomString}-${req.file.originalname}`;
const filepath = `uploads/${filename}`;
const setFilePath = () => { req.file.path = filepath; return next();}
(/\.(gif|bmp)$/i.test(req.file.originalname))
? fs.writeFile(filepath, req.file.buffer, (err) => {
if (err) {
return res.status(500).json({ err: `There was a problem saving the image.`});
next();
}
setFilePath();
})
: sharp(req.file.buffer).resize(256, 256).max().withoutEnlargement().toFile(filepath).then(() => setFilePath())
यदि फ़ाइल सहेजी जाती है, तो यह एक req.file.path
भेजती है मेरे create
. के लिए नियंत्रक यह मेरे डीबी में फ़ाइल पथ के रूप में और छवि पथ के रूप में सहेजा जाता है (avatarFilePath
या /uploads/imagefile.ext
हटाने के उद्देश्यों के लिए सहेजा गया है और avatarURL
या [http://localhost:4000]/uploads/imagefile.ext
सहेजा जाता है और फ्रंट-एंड GET अनुरोध के लिए उपयोग किया जाता है):
नियंत्रक/अवतार.js (मैं पोस्टग्रेज का उपयोग कर रहा हूं, लेकिन आप मोंगो के लिए स्थानापन्न कर सकते हैं)
create: async (req, res, done) => {
try {
const avatarurl = `${apiURL}/${req.file.path}`;
await db.result("INSERT INTO avatars(userid, avatarURL, avatarFilePath) VALUES ($1, $2, $3)", [req.session.id, avatarurl, req.file.path]);
res.status(201).json({ avatarurl });
} catch (err) { return res.status(500).json({ err: err.toString() }); done();
}
फिर जब फ्रंट-एंड uploads
. तक पहुंचने का प्रयास करता है <img src={avatarURL} alt="image" />
. के माध्यम से फ़ोल्डर या <img src="[http://localhost:4000]/uploads/imagefile.ext" alt="image" />
, इसे माइक्रोसर्विस द्वारा परोसा जाता है:
libs/server.js
const express = require("express");
const path = app.get("path");
const PORT = 4000;
//============================================================//
// EXPRESS SERVE AVATAR IMAGES
//============================================================//
app.use(`/uploads`, express.static(`uploads`));
//============================================================//
/* CREATE EXPRESS SERVER */
//============================================================//
app.listen(PORT);
अनुरोध लॉग करते समय यह कैसा दिखता है:
19:17:54 INSERT INTO avatars(userid, avatarURL, avatarFilePath) VALUES ('08861626-b6d0-11e8-9047-672b670fe126', 'http://localhost:4000/uploads/1536891474536-k9c7OdimjEWYXbjTIs9J4S3lh2ldrzV8-android.png', 'uploads/1536891474536-k9c7OdimjEWYXbjTIs9J4S3lh2ldrzV8-android.png')
POST /api/avatar/create 201 109 - 61.614 ms
GET /uploads/1536891474536-k9c7OdimjEWYXbjTIs9J4S3lh2ldrzV8-android.png 200 3027 - 3.877 ms
सफल GET अनुरोध पर उपयोगकर्ता क्या देखता है: