2016 अपडेट
एक्सप्रेस और बिना एक्सप्रेस के उदाहरण जो वास्तव में काम करते हैं
यह सवाल 5 साल से अधिक पुराना है लेकिन हर उत्तर में कुछ समस्याएं हैं ।
टी एल; डॉ
उदाहरणों के लिए नीचे स्क्रॉल करें
express.static
express
connect
http
net
सभी उदाहरण GitHub पर भी हैं: https://github.com/rsp/node-static-http.sersers
परीक्षा परिणाम ट्रैविस पर उपलब्ध हैं: https://travis-ci.org/rsp/node-static-http-servers
परिचय
5 वर्षों के बाद से यह सवाल पूछा गया था कि सामान्यजन द्वारा केवल एक सही उत्तर है, लेकिन भले ही उस उत्तर में कोड के साथ कोई समस्या नहीं है, लेकिन रिसेप्शन के साथ कुछ समस्याएं हैं । यह टिप्पणी की गई थी कि " यह बहुत कुछ समझाता नहीं है कि किसी और को कैसे काम पर भरोसा करना है" और इस तथ्य को कितने लोगों ने वोट दिया है यह स्पष्ट रूप से दिखाता है कि बहुत सारी चीजों को स्पष्टीकरण की आवश्यकता है।
सबसे पहले, "Node.js का उपयोग करके छवियों की सेवा कैसे करें" का एक अच्छा जवाब खरोंच से एक स्थिर फ़ाइल सर्वर को लागू नहीं कर रहा है और बुरी तरह से कर रहा है। एक अच्छा जवाब एक्सप्रेस जैसे एक मॉड्यूल का उपयोग कर रहा है जो काम को सही ढंग से करता है ।
उन टिप्पणियों का उत्तर देना जो कहती हैं कि एक्सप्रेस " का उपयोग करने के अलावा किसी और पर निर्भर नहीं करता है कि कैसे काम पाने के लिए किसी और पर भरोसा किया जाए" यह ध्यान दिया जाना चाहिए, कि http
मॉड्यूल का उपयोग पहले से ही किसी और पर निर्भर करता है ताकि काम पूरा हो सके। यदि कोई काम पूरा करने के लिए किसी पर भरोसा नहीं करना चाहता है, तो उसके बजाय कम से कम कच्चे टीसीपी सॉकेट का उपयोग किया जाना चाहिए - जो मैं नीचे दिए गए अपने उदाहरणों में करता हूं।
एक अधिक गंभीर समस्या यह है कि http
मॉड्यूल का उपयोग करने वाले सभी उत्तर यहां टूट गए हैं । वे परिचय देते हैं दौड़ की स्थिति का हैं , असुरक्षित पथ संकल्प जो पथ पर चलने वाले जोखिम का कारण बनेगा , I / O को अवरुद्ध करता है जो पूरी तरह से सभी और अन्य सूक्ष्म समस्याओं पर किसी भी समवर्ती अनुरोधों की सेवा करने में विफल हो जाएगा - वे पूरी तरह से टूट जाते हैं उदाहरण के रूप में प्रश्न के बारे में क्या पूछता है, और अभी तक वे पहले से ही अमूर्त का उपयोग करते हैं जो द्वारा प्रदान किया गया हैhttp
टीसीपी सॉकेट्स का उपयोग करने के बजाय मॉड्यूल ताकि वे खरोंच से सब कुछ भी न करें जैसा कि वे दावा करते हैं।
यदि यह सवाल था कि "स्थैतिक फ़ाइल सर्वर को खरोंच से कैसे लागू किया जाए, एक सीखने के अभ्यास के रूप में" तो हर तरह से जवाब दिया जाता है कि कैसे पोस्ट किया जाना चाहिए - लेकिन फिर भी हमें उनसे कम से कम सही होने की उम्मीद करनी चाहिए । इसके अलावा, यह मान लेना अनुचित नहीं है कि कोई व्यक्ति जो छवि की सेवा करना चाहता है वह भविष्य में अधिक छवियों की सेवा करना चाहता है, इसलिए कोई यह तर्क दे सकता है कि एक विशिष्ट कस्टम स्टैटिक फ़ाइल सर्वर लिखना जो हार्ड-कोडित पथ के साथ केवल एक ही फ़ाइल की सेवा कर सकता है। कुछ कम है। यह कल्पना करना कठिन लगता है कि जो कोई भी एक छवि की सेवा करने के बारे में एक उत्तर की खोज करता है, वह एक समाधान के साथ संतुष्ट होगा जो किसी भी छवि की सेवा करने के लिए सामान्य समाधान के बजाय सिर्फ एक छवि प्रदान करता है।
संक्षेप में, सवाल यह है कि एक छवि की सेवा कैसे की जाती है और इसका उत्तर एक उचित मॉड्यूल का उपयोग करना है जो कि सुरक्षित, बेहतर और विश्वसनीय तरीके से है जो पेशेवर नोड के सर्वोत्तम अभ्यास का उपयोग करते समय पठनीय, बनाए रखने योग्य और भविष्य के प्रमाण के रूप में है। विकास। लेकिन मैं मानता हूं कि इस तरह के जवाब के लिए एक महान जोड़ एक ही कार्यक्षमता को मैन्युअल रूप से लागू करने का एक रास्ता दिखा रहा होगा लेकिन दुख की बात है कि ऐसा करने का हर प्रयास अब तक विफल रहा है। और इसीलिए मैंने कुछ नए उदाहरण लिखे।
इस छोटे से परिचय के बाद, यहाँ मेरे पाँच उदाहरण हैं जो अमूर्तता के 5 विभिन्न स्तरों पर काम कर रहे हैं।
न्यूनतम कार्यक्षमता
हर उदाहरण public
निर्देशिका से फाइल पेश करता है और इसकी न्यूनतम कार्यक्षमता का समर्थन करता है:
- अधिकांश सामान्य फ़ाइलों के लिए MIME प्रकार
- HTML, JS, CSS, सादा पाठ और चित्र प्रदान करता है
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
मिडिलवेयर के बिना । स्टैटिक का उपयोग करते हुए स्टैटिक फाइल्स की सर्विसिंग को सिंगल रूट हैंडलर के रूप में लागू किया जाता है।
इस उदाहरण में सरल पथ ट्रैवर्सल काउंटरमेशर्स हैं और अधिकांश सामान्य MIME प्रकारों के सीमित सेट का समर्थन करते हैं।
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
संस्करण के समान कार्यक्षमता है लेकिन थोड़ा कम-लीवर एपीआई का उपयोग करना।
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 के लिए निम्नतम-स्तरीय एपीआई है।
इस उदाहरण में 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
मॉड्यूल का उपयोग करता है जो कि नोड में टीसीपी सॉकेट्स के लिए निम्नतम-स्तरीय एपीआई है।
इस उदाहरण में http
संस्करण की कुछ कार्यक्षमता है लेकिन न्यूनतम और अपूर्ण HTTP प्रोटोकॉल को खरोंच से लागू किया गया है। चूँकि यह chunked एन्कोडिंग का समर्थन नहीं करता है इसलिए यह फ़ाइलों को स्मृति में भेजने से पहले उन्हें एक प्रतिक्रिया भेजने से पहले आकार जानने के लिए लोड करता है क्योंकि फ़ाइलों को स्टेट करना और फिर लोड करना एक दौड़ की स्थिति का परिचय देगा।
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/');
});
उदाहरण डाउनलोड करें
मैंने अधिक स्पष्टीकरण के साथ GitHub पर सभी उदाहरण पोस्ट किए।
उदाहरण के साथ express.static
, express
, connect
, http
और net
:
केवल उपयोग करने वाली अन्य परियोजना express.static
:
टेस्ट
ट्रैविस पर परीक्षण के परिणाम उपलब्ध हैं:
सब कुछ नोड संस्करण 4, 5, 6 और 7 पर परीक्षण किया गया है।
यह सभी देखें
अन्य संबंधित उत्तर: