Node.js quick file server (static files over HTTP)
Solution 1
A good "ready-to-use tool" option could be http-server:
npm install http-server -g
To use it:
cd D:\Folder
http-server
Or, like this:
http-server D:\Folder
Check it out: https://github.com/nodeapps/http-server
Solution 2
If you do not want to use ready tool, you can use the code below, as demonstrated by me at https://developer.mozilla.org/en-US/docs/Node_server_without_framework:
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function (request, response) {
console.log('request starting...');
var filePath = '.' + request.url;
if (filePath == './')
filePath = './index.html';
var extname = path.extname(filePath);
var contentType = 'text/html';
switch (extname) {
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
case '.json':
contentType = 'application/json';
break;
case '.png':
contentType = 'image/png';
break;
case '.jpg':
contentType = 'image/jpg';
break;
case '.wav':
contentType = 'audio/wav';
break;
}
fs.readFile(filePath, function(error, content) {
if (error) {
if(error.code == 'ENOENT'){
fs.readFile('./404.html', function(error, content) {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
});
}
else {
response.writeHead(500);
response.end('Sorry, check with the site admin for error: '+error.code+' ..\n');
response.end();
}
}
else {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
}
});
}).listen(8125);
console.log('Server running at http://127.0.0.1:8125/');
UPDATE If you need to access your server from external demand/file, you need to overcome the CORS, in your node.js file by writing the below, as I mentioned in a previous answer here
// Website you wish to allow to connect
response.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
response.setHeader('Access-Control-Allow-Credentials', true);
UPDATE
As Adrian mentioned, in the comments, he wrote an ES6 code with full explanation here, I just re-posting his code below, in case the code gone from the original site for any reason:
const http = require('http');
const url = require('url');
const fs = require('fs');
const path = require('path');
const port = process.argv[2] || 9000;
http.createServer(function (req, res) {
console.log(`${req.method} ${req.url}`);
// parse URL
const parsedUrl = url.parse(req.url);
// extract URL path
let pathname = `.${parsedUrl.pathname}`;
// based on the URL path, extract the file extension. e.g. .js, .doc, ...
const ext = path.parse(pathname).ext;
// maps file extension to MIME typere
const map = {
'.ico': 'image/x-icon',
'.html': 'text/html',
'.js': 'text/javascript',
'.json': 'application/json',
'.css': 'text/css',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.wav': 'audio/wav',
'.mp3': 'audio/mpeg',
'.svg': 'image/svg+xml',
'.pdf': 'application/pdf',
'.doc': 'application/msword'
};
fs.exists(pathname, function (exist) {
if(!exist) {
// if the file is not found, return 404
res.statusCode = 404;
res.end(`File ${pathname} not found!`);
return;
}
// if is a directory search for index file matching the extension
if (fs.statSync(pathname).isDirectory()) pathname += '/index' + ext;
// read file from file system
fs.readFile(pathname, function(err, data){
if(err){
res.statusCode = 500;
res.end(`Error getting the file: ${err}.`);
} else {
// if the file is found, set Content-type and send data
res.setHeader('Content-type', map[ext] || 'text/plain' );
res.end(data);
}
});
});
}).listen(parseInt(port));
console.log(`Server listening on port ${port}`);
Solution 3
For people wanting a server runnable from within NodeJS script:
You can use expressjs/serve-static which replaces connect.static
(which is no longer available as of connect 3):
myapp.js:
var http = require('http');
var finalhandler = require('finalhandler');
var serveStatic = require('serve-static');
var serve = serveStatic("./");
var server = http.createServer(function(req, res) {
var done = finalhandler(req, res);
serve(req, res, done);
});
server.listen(8000);
and then from command line:
$ npm install finalhandler serve-static
$ node myapp.js
Solution 4
I know it's not Node, but I've used Python's SimpleHTTPServer:
python -m SimpleHTTPServer [port]
It works well and comes with Python.
Solution 5
From [email protected], npm
started installing a new binary alongside the usual npm called npx
. So now, one liners to create static http server from current directory:
npx serve
or
npx http-server
Paul Verest
Java Developer, Architect, Team Leader; Agile Coach, Tech Manager Authoring Nodeclipse, Anide.js, Enide Organizing http://szjug.github.io/ Building up JVMs, Spring.io and Node.js User Groups (Java, Groovy, Scala, Android, JavaScript)
Updated on July 08, 2022Comments
-
Paul Verest almost 2 years
Is there Node.js ready-to-use tool (installed with
npm
), that would help me expose folder content as file server over HTTP.Example, if I have
D:\Folder\file.zip D:\Folder\file2.html D:\Folder\folder\file-in-folder.jpg
Then starting in
D:\Folder\
node node-file-server.js
I could access file viahttp://hostname/file.zip http://hostname/file2.html http://hostname/folder/file-in-folder.jpg
Why is my node static file server dropping requests? reference some mystical
standard node.js static file server
If there's no such tool, what framework should I use?
Related: Basic static file server in NodeJS
-
Paul Verest about 11 yearsCan I $ npm install -g express ; them $ express ?
-
Tim Heap about 11 yearsI built that server. That file server was built against a very old version of Node, hence why it does not work any more. I do not have the time right now to fix it up. I suggest using the answer by @Oleg above. It can be easily bundled into a small node executable, and is essentially what mine did anyway.
-
Paul Verest about 11 yearsThank you Tim, very professional response. I wouldn't delete code though, but update readme.
-
jakub.g almost 10 yearsThis does not work any longer as of connect 3 as it doesn't expose
connect.static
; see my answer below for a replacement -
Oleg almost 10 yearsI believe that it is still bundled with express by default, but indeed exists now in a separate
require
able module "serve-static". -
Lee Jenkins over 9 yearsFYI This did not work for me. I installed filehandler using
npm install filehandler
and the package is listed in thenode_modules
directory. But when I runmyapp.js
node throws an error, sayingError: cannot find module filehandler
. If I comment out the require ststment to load filehandler the app loads serve-static just fine, so it looks like there's something wrong with the filhandler package. Today is December 12, 2014, so maybe the package has changed since this answer was posted? -
jakub.g over 9 yearsIt's
final
handler notfile
-
jakub.g over 9 yearsPython3 equivalent:
python -m http.server [port]
(the mentioned one is for Python2) -
Sam Berry about 9 yearsThis is awesome. I needed to specify an address bc for some reason the default 0.0.0.0 wasn't cooperating w my dev environment.
http-server -a localhost
got er dun. -
Muhammad Umer almost 9 yearsi use
http-server -a localhost -p 80
-
bigtunacan almost 9 yearsYeah; it's slightly weird in that it doesn't automap localhost, but you can access from 0.0.0.0:8080
-
Thomas Hunter II over 8 yearsSurely,
response.writeHead(200
should beresponse.writeHead(404
;) -
JsAndDotNet over 8 yearsUpdate - My answer works, but I now use @Matt Self's answer of using http-server. It seems to work well.
-
Dheeraj Sam over 8 yearsThank you so much! That was simple! ;)
-
garryp over 8 yearsDoesn't get much simpler than this
-
Bill over 8 yearsCorrect me if I am wrong, but if you get 404 it still writes the content type as if it was whatever was requested, instead of text/html?
-
Abhinav Gauniyal over 8 yearsYou should add some explanation alog with this code.
-
Rolf over 8 yearsWould that code not allow going up the file tree by doing something like 127.0.0.1/../../../etc/passwd ? I see no checks against that.
-
Zimy about 8 yearsPython fails for me when it is about serving large files like OS images. Fedora 23
-
szhuravel about 8 yearshttp-server works well for me on Windows. Btw, http-server -o opens my default browser with index page on 127.0.0.1:8080. Also there is a bunch of other useful parameters. For quick tests it's really the best tool.
-
Adrian almost 8 yearsIf anyone interested in the ES6+ version, I created a static file server that handles MIME types: gist.github.com/amejiarosario/53afae82e18db30dadc9bc39035778e5
-
Hasan A Yousef almost 8 years@Adrian, well done, thanks for your added value comment.
-
Nick F over 7 yearsThe advantage of using Browsersync rather than other static servers is that it live updates the page whenever the files specified by the
--files
flag change (nb. you don't need to specify./*
- only the ones that you want Browsersync to actively watch for updates, eg.css/*.css
) -
Nick F over 7 yearsIt's worth checking browser-sync too, which can do more-or-less the same thing but with the added bonus of live-updating when files are modified.
-
Wei Xia over 7 yearsHi, I can run it correctly, but it shows
Cannot GET /
. I use AWS EC2 to run the server. -
pasx over 7 years@Wei Hi, late answer. From what I can see from a quick Google search it looks like your directory structure might be wrong. There must be an index.html file in the location you are targeting. Setting up the above example to run should take 5 minutes and I double checked that it works as is. From there you can tweak the path to suit your directory structure and check that the server still finds the files it needs to server.
-
klimat over 7 yearsanother advantage of this solution is, files aren't cached, so you don't need to restart a process when making changes in code.
-
dennis about 7 yearsAnd on PHP:
php -S localhost:8000
-
Adrian Lynch about 7 yearsI use this to quickly serve content from a folder all the time.
-
Giorgi Moniava about 7 yearsin your example you have: response.end(content, 'utf-8'); , how it will send binary file if you set utf8 as encoding?
-
Daniel F about 7 years
--cors
to sendAccess-Control-Allow-Origin:*
along with the response headers (ie when serving a json file) -
Eduard Bondarenko about 7 yearsDon't use the sync version. Instread create pipe to res from readStream.
-
AceMark almost 7 yearsa very good tool. helped me out right now. kudos to @indexzero
-
Seph Reed almost 7 years@Adrian This code is very awesome, but I have found a way to get root access with it. The solution is to limit the amount of leading periods on the filename to one so you can't do
../../etc/password
stuff. gist.github.com/amejiarosario/53afae82e18db30dadc9bc39035778e5 -
Seph Reed almost 7 years
pathname = pathname.replace(/^(\.)+/, '.');
-
sdgfsdh almost 7 years
path.join(__dirname, 'public')
is more cross-platform. -
Qwerty over 6 yearsI followed your steps, but my express does not have bin folder
-
Qwerty over 6 yearsThis also watches for changes and provides live reload.
-
singhpradeep over 6 yearsawesome dude... simple and plain answer without third party API to read and send static contents to client.
-
abentan over 6 yearsExcellent quick server version! Thanks. I am using font-awesome and got some problems, 404, because the filepath include a query: localhost:8484/fonts/fontawesome-webfont.woff2?v=4.3.0 and the extension can't be recognized. Can use this to fix it, add: var url = require('url'); and replace the filePath with: var q = url.parse(request.url, true); var filePath = '.' + q.pathname; to retrieve the pathname without the query.
-
Chirag Parekh over 6 yearsThanks. This is the really awesome solution.
-
Colin over 6 yearsI found useful
live-server
for development it watches changes. -
Coli about 6 yearsBecause
exists
is deprecated, you should usefs.access
instead. @HasanAYousef -
The Anh Nguyen about 6 yearsVery nice! But for me, I need extra fuction like Basic Authentication. It will be awesome
-
Faris Rayhan almost 6 yearsThis is absolutely awesome tool. Damn it :)
-
collapsar almost 6 yearsBest answer if you need a quick & dirty one-time one trick pony.
-
Mike McKay over 5 years
npx http-server
- npx turns it into a one-liner that downloads the necessary files and runs it. -
William Jones over 5 yearsIt just downloads the file for me.
-
Hamzeen Hameem over 5 yearstry this if you haven't installed
http-server
globally:npx http-server -a 0.0.0.0 -p 80
this way your server will be accessible by all the machines that share the same network as yours. -
derickito about 5 yearsYou realize that
npm
is the node package manager so you're in fact using the NodeJS stuff -
Diego Mendes about 5 yearsI do, What I meant as "NodeJS stuff" was using NodeJS and express to serve the files like most answers suggested. Serve is an independent executable, NPM is used just to install it, you could just download it directly.
-
Joseph Cho about 5 yearsIf you want to avoid using
index.html
as part of your address just addif (req.url === '/') req.url = '/index.html';
right afterres.writeHead(200);
. -
Justin Meiners about 5 years@EduardBondarenko is right.
const stream = fs.createReadStream(...); stream.pipe(res);
is all you need -
Ashkan Hovold over 4 yearsThis is beautiful! Got my static website running with a single command instead of having to install some extra web server!
-
FrenkyB over 4 yearsIs this also possible with https-server ?
-
akauppi over 3 yearsFor simple development tasks, I've found your approach to be better than bringing in some 'out of the box' service. No added dependencies, ability to do unorthodox things (today, I needed to do routing, and servers don't usually do it).
-
arthurDent over 3 yearsThis is a C++ Server which has no relation to a Node.js Solution. Also the name is misleading in this Thread because it shares it's name with a popular MongoDB Layer for Node.js.
-
Blaise about 3 yearsNodeJs equivalent
npx http-server [-p 8000] [<dir>]
-
rahul about 3 yearsI cannot download multiple files simultaneously with python server. Any work around for that?
-
Spongebob Comrade about 2 yearsso cool .......... :D
-
Paflow about 2 yearsLot's of error in this. Variable names are not consistend (response, res etc).