2016 আপডেট
এক্সপ্রেসের সাথে এবং এক্সপ্রেস ছাড়াই যেগুলি বাস্তবে কাজ করে Ex
এই প্রশ্নটি 5 বছরেরও বেশি পুরানো তবে প্রতিটি উত্তরের কিছু সমস্যা রয়েছে ।
টি এল; ডিআর
এর সাথে একটি চিত্র পরিবেশন করতে উদাহরণগুলির জন্য নীচে স্ক্রোল করুন:
express.static
express
connect
http
net
সমস্ত উদাহরণ গীতহাব এও রয়েছে: https://github.com/rsp/node-static-http-servers
পরীক্ষার ফলাফল ট্র্যাভিসে পাওয়া যায়: https://travis-ci.org/rsp/node-static-http-servers
ভূমিকা
এই প্রশ্নটি 5 বছরেরও বেশি পরে যেহেতু জেনারেনেরির দ্বারা কেবল একটি সঠিক উত্তর রয়েছে তবে যদিও উত্তরটির কোডটির সাথে কোনও সমস্যা নেই, তবে মনে হচ্ছে অভ্যর্থনা নিয়ে কিছু সমস্যা আছে । এটি মন্তব্য করা হয়েছিল যে এটি "কীভাবে অন্য কারও উপর নির্ভর করে কাজটি করা যায় তার চেয়ে অনেক বেশি ব্যাখ্যা করে না" এবং কতজন লোক এই মন্তব্যটিতে ভোট দিয়েছে তা স্পষ্টভাবে দেখায় যে অনেক কিছুর স্পষ্টতা প্রয়োজন।
প্রথমত, "নোড.জেএস ব্যবহার করে কীভাবে চিত্রগুলি পরিবেশন করা যায়" এর একটি ভাল উত্তর স্ক্র্যাচ থেকে কোনও স্ট্যাটিক ফাইল সার্ভার প্রয়োগ করছে না এবং এটি খারাপভাবে করছে। একটি ভাল উত্তর এক্সপ্রেসের মতো একটি মডিউল ব্যবহার করছে যা কাজটি সঠিকভাবে করে ।
এক্সপ্রেস ব্যবহার করা "কাজটি করার জন্য কীভাবে অন্যের উপর নির্ভর করতে হবে তার চেয়ে অনেক বেশি ব্যাখ্যা করে না" এমন মন্তব্যের জবাব দেওয়া উচিত, এটি উল্লেখ করা উচিত যে httpমডিউলটি ইতিমধ্যে অন্য কারও উপর নির্ভর করে কাজটি সম্পন্ন করার জন্য। যদি কেউ কাজটি পেতে কারও উপর নির্ভর করতে না চান তবে তার পরিবর্তে কমপক্ষে কাঁচা টিসিপি সকেট ব্যবহার করা উচিত - যা আমি নীচের আমার একটি উদাহরণে করি।
আরও গুরুতর সমস্যা হ'ল এখানে যে উত্তরগুলি httpমডিউলটি ব্যবহার করে তার সবগুলিই নষ্ট হয়ে যায় । তারা বর্ণের পরিস্থিতি , অনিরাপদ পথের সমাধানের প্রবর্তন করে যা পথ ট্র্যাভারসাল দুর্বলতার দিকে নিয়ে যায় , I / O কে অবরুদ্ধ করে যা কোনও সময়ে এবং অন্যান্য সূক্ষ্ম সমস্যাগুলিতে কোনও একযোগের অনুরোধগুলি পরিপূর্ণ করতে ব্যর্থ হবে - প্রশ্নটি যা জিজ্ঞাসা করে তার উদাহরণ হিসাবে তারা সম্পূর্ণরূপে ভেঙে যায়, এবং তবুও তারা ইতিমধ্যে httpটিসিপি সকেট ব্যবহার না করে মডিউল দ্বারা সরবরাহিত বিমূর্ততাটি ব্যবহার করে যাতে তারা দাবি হিসাবে স্ক্র্যাচ থেকে সবকিছু না করে।
যদি প্রশ্নটি ছিল "স্ক্র্যাচ থেকে স্থিতিশীল ফাইল সার্ভারটি কীভাবে প্রয়োগ করা যায়, একটি শেখার অনুশীলন হিসাবে" তবে সমস্ত উপায়ে উত্তর কীভাবে তা পোস্ট করা উচিত - তবে তারপরেও আমাদের কমপক্ষে সঠিক হওয়া আশা করা উচিত । এছাড়াও, এটি ধরে নেওয়া অযৌক্তিক নয় যে যে কেউ চিত্র পরিবেশন করতে চায় সে ভবিষ্যতে আরও চিত্র সরবরাহ করতে চায় যাতে কেউ যুক্তি দিতে পারে যে একটি নির্দিষ্ট কাস্টম স্ট্যাটিক ফাইল সার্ভার লিখতে পারে যা হার্ড-কোডিং পথের সাথে কেবল একটি একক ফাইল পরিবেশন করতে পারে কিছুটা সংক্ষিপ্ত এটি ধারণা করা শক্ত বলে মনে হয় যে যে কেউ কীভাবে কোনও চিত্র পরিবেশন করতে পারে সে সম্পর্কে একটি উত্তর অনুসন্ধান করে এমন কোনও সমাধানে সন্তুষ্ট হবে যা কোনও চিত্রের পরিবেশনার জন্য সাধারণ সমাধানের পরিবর্তে কেবল একটি একক চিত্র পরিবেশন করে।
সংক্ষেপে, প্রশ্ন হল পেশাদার নোডের সর্বোত্তম অনুশীলনটি ব্যবহার করার সময় পাঠযোগ্য, রক্ষণাবেক্ষণযোগ্য এবং ভবিষ্যত- প্রমাণযোগ্য সুরক্ষিত, পূর্বনির্ধারিত এবং নির্ভরযোগ্য উপায়ে এটি করার জন্য একটি উপযুক্ত মডিউলটি কীভাবে ব্যবহার করতে হয় এবং তার উত্তর কীভাবে দেওয়া হয়? উন্নয়ন। তবে আমি সম্মত হই যে এই জাতীয় উত্তরের একটি দুর্দান্ত সংযোজন হ'ল ম্যানুয়ালি একই কার্যকারিতা বাস্তবায়নের জন্য একটি উপায় দেখানো হবে তবে দুঃখের বিষয় যে এটি করার প্রতিটি প্রচেষ্টা এখনও ব্যর্থ হয়েছে। এবং সে কারণেই আমি কয়েকটি নতুন উদাহরণ লিখেছি।
এই সংক্ষিপ্ত পরিচিতির পরে, বিমূর্তনের 5 টি বিভিন্ন স্তরে আমার কাজ করা 5 টি উদাহরণ এখানে রয়েছে।
সর্বনিম্ন কার্যকারিতা
প্রতিটি উদাহরণ publicডিরেক্টরি থেকে ফাইলগুলি সরবরাহ করে এবং এর সর্বনিম্ন কার্যকারিতা সমর্থন করে:
- সর্বাধিক সাধারণ ফাইলগুলির জন্য মাইমে টাইপ types
- এইচটিএমএল, জেএস, সিএসএস, সরল পাঠ্য এবং চিত্র পরিবেশন করে
index.htmlএকটি ডিফল্ট ডিরেক্টরি সূচক হিসাবে কাজ করে
- অনুপস্থিত ফাইলগুলির জন্য ত্রুটি কোডগুলির সাথে প্রতিক্রিয়া জানায়
- কোনও পথ ট্র্যাভারসাল দুর্বলতা নেই
- ফাইল পড়ার সময় কোনও রেসের শর্ত নেই
আমি নোড সংস্করণ 4, 5, 6 এবং 7 এর প্রতিটি সংস্করণ পরীক্ষা করেছি।
express.static
এই সংস্করণটি মডিউলটির express.staticঅন্তর্নির্মিত মিডলওয়্যার ব্যবহার করে express।
এই উদাহরণটিতে সর্বাধিক কার্যকারিতা এবং কোডের সর্বনিম্ন পরিমাণ রয়েছে।
var path = require('path');
var express = require('express');
var app = express();
var dir = path.join(__dirname, 'public');
app.use(express.static(dir));
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
express
এই সংস্করণটি expressমডিউলটি ব্যবহার করে তবে express.staticমিডওয়্যারটি ছাড়াই । স্ট্যাটিক ফাইলগুলি পরিবেশন করা স্ট্রিম ব্যবহার করে একক রুট হ্যান্ডলার হিসাবে প্রয়োগ করা হয়।
এই উদাহরণে সরল পথ ট্র্যাভারসাল কাউন্টারমেজার রয়েছে এবং বেশিরভাগ সাধারণ এমআইএমআই টাইপের একটি সীমিত সেট সমর্থন করে।
var path = require('path');
var express = require('express');
var app = express();
var fs = require('fs');
var dir = path.join(__dirname, 'public');
var mime = {
html: 'text/html',
txt: 'text/plain',
css: 'text/css',
gif: 'image/gif',
jpg: 'image/jpeg',
png: 'image/png',
svg: 'image/svg+xml',
js: 'application/javascript'
};
app.get('*', function (req, res) {
var file = path.join(dir, req.path.replace(/\/$/, '/index.html'));
if (file.indexOf(dir + path.sep) !== 0) {
return res.status(403).end('Forbidden');
}
var type = mime[path.extname(file).slice(1)] || 'text/plain';
var s = fs.createReadStream(file);
s.on('open', function () {
res.set('Content-Type', type);
s.pipe(res);
});
s.on('error', function () {
res.set('Content-Type', 'text/plain');
res.status(404).end('Not found');
});
});
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
connect
এই সংস্করণটি connectমডিউলটি ব্যবহার করে যা বিমূর্ততার চেয়ে এক স্তর কম express।
এই উদাহরণটির expressসংস্করণটির সাথে অনুরূপ কার্যকারিতা রয়েছে তবে কিছুটা নিম্ন-লিভারের API ব্যবহার করা।
var path = require('path');
var connect = require('connect');
var app = connect();
var fs = require('fs');
var dir = path.join(__dirname, 'public');
var mime = {
html: 'text/html',
txt: 'text/plain',
css: 'text/css',
gif: 'image/gif',
jpg: 'image/jpeg',
png: 'image/png',
svg: 'image/svg+xml',
js: 'application/javascript'
};
app.use(function (req, res) {
var reqpath = req.url.toString().split('?')[0];
if (req.method !== 'GET') {
res.statusCode = 501;
res.setHeader('Content-Type', 'text/plain');
return res.end('Method not implemented');
}
var file = path.join(dir, reqpath.replace(/\/$/, '/index.html'));
if (file.indexOf(dir + path.sep) !== 0) {
res.statusCode = 403;
res.setHeader('Content-Type', 'text/plain');
return res.end('Forbidden');
}
var type = mime[path.extname(file).slice(1)] || 'text/plain';
var s = fs.createReadStream(file);
s.on('open', function () {
res.setHeader('Content-Type', type);
s.pipe(res);
});
s.on('error', function () {
res.setHeader('Content-Type', 'text/plain');
res.statusCode = 404;
res.end('Not found');
});
});
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
http
এই সংস্করণটি httpমডিউলটি ব্যবহার করে যা নোডের HTTP- র জন্য সর্বনিম্ন-স্তরের API।
এই উদাহরণটির connectসংস্করণে অনুরূপ কার্যকারিতা রয়েছে তবে আরও নিম্ন-স্তরের এপিআই ব্যবহার করে।
var path = require('path');
var http = require('http');
var fs = require('fs');
var dir = path.join(__dirname, 'public');
var mime = {
html: 'text/html',
txt: 'text/plain',
css: 'text/css',
gif: 'image/gif',
jpg: 'image/jpeg',
png: 'image/png',
svg: 'image/svg+xml',
js: 'application/javascript'
};
var server = http.createServer(function (req, res) {
var reqpath = req.url.toString().split('?')[0];
if (req.method !== 'GET') {
res.statusCode = 501;
res.setHeader('Content-Type', 'text/plain');
return res.end('Method not implemented');
}
var file = path.join(dir, reqpath.replace(/\/$/, '/index.html'));
if (file.indexOf(dir + path.sep) !== 0) {
res.statusCode = 403;
res.setHeader('Content-Type', 'text/plain');
return res.end('Forbidden');
}
var type = mime[path.extname(file).slice(1)] || 'text/plain';
var s = fs.createReadStream(file);
s.on('open', function () {
res.setHeader('Content-Type', type);
s.pipe(res);
});
s.on('error', function () {
res.setHeader('Content-Type', 'text/plain');
res.statusCode = 404;
res.end('Not found');
});
});
server.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
net
এই সংস্করণটি netমডিউলটি ব্যবহার করে যা নোডের টিসিপি সকেটের জন্য সর্বনিম্ন-স্তরের API।
এই উদাহরণে httpসংস্করণটির কিছু কার্যকারিতা রয়েছে তবে ন্যূনতম এবং অসম্পূর্ণ এইচটিটিপি প্রোটোকল স্ক্র্যাচ থেকে কার্যকর করা হয়েছে। যেহেতু এটি খণ্ডিত এনকোডিং সমর্থন করে না এটি প্রতিক্রিয়া প্রেরণের আগে আকারটি জানার আগে ফাইলগুলি মেমোরিতে লোড করে কারণ ফাইলগুলি স্থির করে এবং তারপরে লোড একটি জাতি শর্ত প্রবর্তন করবে।
var path = require('path');
var net = require('net');
var fs = require('fs');
var dir = path.join(__dirname, 'public');
var mime = {
html: 'text/html',
txt: 'text/plain',
css: 'text/css',
gif: 'image/gif',
jpg: 'image/jpeg',
png: 'image/png',
svg: 'image/svg+xml',
js: 'application/javascript'
};
var server = net.createServer(function (con) {
var input = '';
con.on('data', function (data) {
input += data;
if (input.match(/\n\r?\n\r?/)) {
var line = input.split(/\n/)[0].split(' ');
var method = line[0], url = line[1], pro = line[2];
var reqpath = url.toString().split('?')[0];
if (method !== 'GET') {
var body = 'Method not implemented';
con.write('HTTP/1.1 501 Not Implemented\n');
con.write('Content-Type: text/plain\n');
con.write('Content-Length: '+body.length+'\n\n');
con.write(body);
con.destroy();
return;
}
var file = path.join(dir, reqpath.replace(/\/$/, '/index.html'));
if (file.indexOf(dir + path.sep) !== 0) {
var body = 'Forbidden';
con.write('HTTP/1.1 403 Forbidden\n');
con.write('Content-Type: text/plain\n');
con.write('Content-Length: '+body.length+'\n\n');
con.write(body);
con.destroy();
return;
}
var type = mime[path.extname(file).slice(1)] || 'text/plain';
var s = fs.readFile(file, function (err, data) {
if (err) {
var body = 'Not Found';
con.write('HTTP/1.1 404 Not Found\n');
con.write('Content-Type: text/plain\n');
con.write('Content-Length: '+body.length+'\n\n');
con.write(body);
con.destroy();
} else {
con.write('HTTP/1.1 200 OK\n');
con.write('Content-Type: '+type+'\n');
con.write('Content-Length: '+data.byteLength+'\n\n');
con.write(data);
con.destroy();
}
});
}
});
});
server.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
উদাহরণ ডাউনলোড করুন
আমি আরও ব্যাখ্যা সহ গিটহাবের সমস্ত উদাহরণ পোস্ট করেছি।
উদাহরণ express.static, express, connect, httpএবং net:
অন্যান্য প্রকল্প কেবল ব্যবহার করে express.static:
টেস্ট
ট্র্যাভিসে পরীক্ষার ফলাফল পাওয়া যায়:
নোড সংস্করণ 4, 5, 6 এবং 7-তে সমস্ত কিছু পরীক্ষা করা হয়।
আরো দেখুন
অন্যান্য সম্পর্কিত উত্তর: