Node.js quick file server (static files over HTTP) - node.js
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 via
http://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
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
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}`);
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
I know it's not Node, but I've used Python's SimpleHTTPServer:
python -m SimpleHTTPServer [port]
It works well and comes with Python.
From npm#5.2.0, 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
connect could be what you're looking for.
Installed easily with:
npm install connect
Then the most basic static file server could be written as:
var connect = require('connect'),
directory = '/path/to/Folder';
connect()
.use(connect.static(directory))
.listen(80);
console.log('Listening on port 80.');
One-line™ Proofs instead of promises
The first is http-server, hs - link
npm i -g http-server // install
hs C:\repos // run with one line?? FTW!!
The second is serve by ZEIT.co - link
npm i -g serve // install
serve C:\repos // run with one line?? FTW!!
Following are available options, if this is what helps you decide.
C:\Users\Qwerty>http-server --help
usage: http-server [path] [options]
options:
-p Port to use [8080]
-a Address to use [0.0.0.0]
-d Show directory listings [true]
-i Display autoIndex [true]
-g --gzip Serve gzip files when possible [false]
-e --ext Default file extension if none supplied [none]
-s --silent Suppress log messages from output
--cors[=headers] Enable CORS via the "Access-Control-Allow-Origin" header
Optionally provide CORS headers list separated by commas
-o [path] Open browser window after starting the server
-c Cache time (max-age) in seconds [3600], e.g. -c10 for 10 seconds.
To disable caching, use -c-1.
-U --utc Use UTC time format in log messages.
-P --proxy Fallback proxy if the request cannot be resolved. e.g.: http://someurl.com
-S --ssl Enable https.
-C --cert Path to ssl cert file (default: cert.pem).
-K --key Path to ssl key file (default: key.pem).
-r --robots Respond to /robots.txt [User-agent: *\nDisallow: /]
-h --help Print this list and exit.
C:\Users\Qwerty>serve --help
Usage: serve.js [options] [command]
Commands:
help Display help
Options:
-a, --auth Serve behind basic auth
-c, --cache Time in milliseconds for caching files in the browser
-n, --clipless Don't copy address to clipboard (disabled by default)
-C, --cors Setup * CORS headers to allow requests from any origin (disabled by default)
-h, --help Output usage information
-i, --ignore Files and directories to ignore
-o, --open Open local address in browser (disabled by default)
-p, --port Port to listen on (defaults to 5000)
-S, --silent Don't log anything to the console
-s, --single Serve single page applications (sets `-c` to 1 day)
-t, --treeless Don't display statics tree (disabled by default)
-u, --unzipped Disable GZIP compression
-v, --version Output the version number
If you need to watch for changes, see hostr, credit Henry Tseng's answer
Install express using npm: https://expressjs.com/en/starter/installing.html
Create a file named server.js at the same level of your index.html with this content:
var express = require('express');
var server = express();
server.use(express.static(__dirname));
server.listen(8080);
This will load your index.html file. If you wish to specify the html file to load, use this syntax:
server.use('/', express.static(__dirname + '/myfile.html'));
If you wish to put it in a different location, set the path on the third line:
server.use('/', express.static(__dirname + '/public'));
CD to the folder containing your file and run node from the console with this command:
node server.js
Browse to localhost:8080
#DEMO/PROTO SERVER ONLY
If that's all you need, try this:
const fs = require('fs'),
http = require('http'),
arg = process.argv.slice(2),
rootdir = arg[0] || process.cwd(),
port = process.env.PORT || 9000,
hostname = process.env.HOST || '127.0.0.1';
//tested on node=v10.19.0
http.createServer(function (req, res) {
try {
// change 'path///to/////dir' -> 'path/to/dir'
req_url = decodeURIComponent(req.url).replace(/\/+/g, '/');
stats = fs.statSync(rootdir + req_url);
if (stats.isFile()) {
buffer = fs.createReadStream(rootdir + req_url);
buffer.on('open', () => buffer.pipe(res));
return;
}
if (stats.isDirectory()) {
//Get list of files and folder in requested directory
lsof = fs.readdirSync(rootdir + req_url, {encoding:'utf8', withFileTypes:false});
// make an html page with the list of files and send to browser
res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
res.end(html_page(`http://${hostname}:${port}`, req_url, lsof));
return;
}
} catch (err) {
res.writeHead(404);
res.end(err);
return;
}
}).listen(port, hostname, () => console.log(`Server running at http://${hostname}:${port}`));
function html_page(host, req_url, lsof) {//this is a Function declarations can be called before it is defined
// Add link to root directory and parent directory if not already in root directory
list = req_url == '/' ? [] : [`/`,
`..`];
templete = (host, req_url, file) => {// the above is a Function expressions cannot be called before it is defined
return `${file}`; }
// Add all the links to the files and folder in requested directory
lsof.forEach(file => {
list.push(templete(host, req_url, file));
});
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Directory of ${req_url}</title>
</head>
<body>
<h2>Directory of ${req_url}</h2>
${list.join('<br/>\n')}
</body>
</html>`
}
In plain node.js:
const http = require('http')
const fs = require('fs')
const path = require('path')
process.on('uncaughtException', err => console.error('uncaughtException', err))
process.on('unhandledRejection', err => console.error('unhandledRejection', err))
const publicFolder = process.argv.length > 2 ? process.argv[2] : '.'
const port = process.argv.length > 3 ? process.argv[3] : 8080
const mediaTypes = {
zip: 'application/zip',
jpg: 'image/jpeg',
html: 'text/html',
/* add more media types */
}
const server = http.createServer(function(request, response) {
console.log(request.method + ' ' + request.url)
const filepath = path.join(publicFolder, request.url)
fs.readFile(filepath, function(err, data) {
if (err) {
response.statusCode = 404
return response.end('File not found or you made an invalid request.')
}
let mediaType = 'text/html'
const ext = path.extname(filepath)
if (ext.length > 0 && mediaTypes.hasOwnProperty(ext.slice(1))) {
mediaType = mediaTypes[ext.slice(1)]
}
response.setHeader('Content-Type', mediaType)
response.end(data)
})
})
server.on('clientError', function onClientError(err, socket) {
console.log('clientError', err)
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n')
})
server.listen(port, '127.0.0.1', function() {
console.log('👨🔧 Development server is online.')
})
This is a simple node.js server that only serves requested files in a certain directory.
Usage:
node server.js folder port
folder may be absolute or relative depending on the server.js location. The default value is . which is the directory you execute node server.js command.
port is 8080 by default but you can specify any port available in your OS.
In your case, I would do:
cd D:\Folder
node server.js
You can browse the files under D:\Folder from a browser by typing http://127.0.0.1:8080/somefolder/somefile.html
There is another static web server that is quite nice: browser-sync.
It can be downloaded using node package manager:
npm install -g browser-sync
After installation, navigate to the project folder in the cmd prompt and just run the following:
browser-sync start --server --port 3001 --files="./*"
It will start catering all the files in the current folder in the browser.
More can be found out from BrowserSync
Thanks.
Here is my one-file/lightweight node.js static file web-server pet project with no-dependency that I believe is a quick and rich tool which its use is as easy as issuing this command on your Linux/Unix/macOS terminal (or termux on Android) when node.js (or nodejs-legacy on Debian/Ubuntu) is installed:
curl pad.js.org | node
(different commands exist for Windows users on the documentation)
It supports different things that I believe can be found useful,
Hierarchical directory index creation/serving
With sort capability on the different criteria
Upload from browser by [multi-file] drag-and-drop and file/text-only copy-paste and system clipboard screen-shot paste on Chrome, Firefox and other browsers may with some limitations (which can be turned off by command line options it provides)
Folder/note-creation/upload button
Serving correct MIMEs for well known file types (with possibility for disabling that)
Possibility of installation as a npm package and local tool or, one-linear installation as a permanent service with Docker
HTTP 206 file serving (multipart file transfer) for faster transfers
Uploads from terminal and browser console (in fact it was originally intended to be a file-system proxy for JS console of browsers on other pages/domains)
CORS download/uploads (which also can be turned off)
Easy HTTPS integration
Lightweight command line options for achieving better secure serving with it:
With my patch on node.js 8, you can have access to the options without first installation: curl pad.js.org | node - -h
Or first install it as a system-global npm package by [sudo] npm install -g pad.js and then use its installed version to have access to its options: pad -h
Or use the provided Docker image which uses relatively secure options by default. [sudo] docker run --restart=always -v /files:/files --name pad.js -d -p 9090:9090 quay.io/ebraminio/pad.js
The features described above are mostly documented on the main page of the tool http://pad.js.org which by some nice trick I used is also the place the tool source itself is also served from!
The tool source is on GitHub which welcomes your feedback, feature requests and ⭐s!
You can use the NPM serve package for this, if you don't need the NodeJS stuff it is a quick and easy to use tool:
1 - Install the package on your PC:
npm install -g serve
2 - Serve your static folder with serve <path> :
d:> serve d:\StaticSite
It will show you which port your static folder is being served, just navigate to the host like:
http://localhost:3000
I haven't had much luck with any of the answers on this page, however, below seemed to do the trick.
Add a server.js file with the following content:
const express = require('express')
const path = require('path')
const port = process.env.PORT || 3000
const app = express()
// serve static assets normally
app.use(express.static(__dirname + '/dist'))
// handle every other route with index.html, which will contain
// a script tag to your application's JavaScript file(s).
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, 'dist', 'index.html'))
})
app.listen(port)
console.log("server started on port " + port)
Also make sure that you require express. Run yarn add express --save or npm install express --save depending on your setup (I can recommend yarn it's pretty fast).
You may change dist to whatever folder you are serving your content is. For my simple project, I wasn't serving from any folder, so I simply removed the dist filename.
Then you may run node server.js. As I had to upload my project to a Heroku server, I needed to add the following to my package.json file:
"scripts": {
"start": "node server.js"
}
Below worked for me:
Create a file app.js with below contents:
// app.js
var fs = require('fs'),
http = require('http');
http.createServer(function (req, res) {
fs.readFile(__dirname + req.url, function (err,data) {
if (err) {
res.writeHead(404);
res.end(JSON.stringify(err));
return;
}
res.writeHead(200);
res.end(data);
});
}).listen(8080);
Create a file index.html with below contents:
Hi
Start a command line:
cmd
Run below in cmd:
node app.js
Goto below URL, in chrome:
http://localhost:8080/index.html
That's all. Hope that helps.
Source: https://nodejs.org/en/knowledge/HTTP/servers/how-to-serve-static-files/
If you use the Express framework, this functionality comes ready to go.
To setup a simple file serving app just do this:
mkdir yourapp
cd yourapp
npm install express
node_modules/express/bin/express
Searching in NPM registry https://npmjs.org/search?q=server, I have found static-server https://github.com/maelstrom/static-server
Ever needed to send a colleague a file, but can't be bothered emailing
the 100MB beast? Wanted to run a simple example JavaScript
application, but had problems with running it through the file:///
protocol? Wanted to share your media directory at a LAN without
setting up Samba, or FTP, or anything else requiring you to edit
configuration files? Then this file server will make your life that
little bit easier.
To install the simple static stuff server, use npm:
npm install -g static-server
Then to serve a file or a directory, simply run
$ serve path/to/stuff
Serving path/to/stuff on port 8001
That could even list folder content.
Unfortunately, it couldn't serve files :)
You can try serve-me
Using it is so easy:
ServeMe = require('serve-me')();
ServeMe.start(3000);
Thats all.
PD: The folder served by default is "public".
Here's another simple web server.
https://www.npmjs.com/package/hostr
Install
npm install -g hostr
Change working director
cd myprojectfolder/
And start
hostr
For a healthy increase of performance using node to serve static resources, I recommend using Buffet. It works similar to as a web application accelerator also known as a caching HTTP reverse proxy but it just loads the chosen directory into memory.
Buffet takes a fully-bufferred approach -- all files are fully loaded into memory when your app boots, so you will never feel the burn of the filesystem. In practice, this is immensely efficient. So much so that putting Varnish in front of your app might even make it slower!
We use it on the codePile site and found an increase of ~700requests/sec to >4k requests/sec on a page that downloads 25 resources under a 1k concurrent user connection load.
Example:
var server = require('http').createServer();
var buffet = require('buffet')(root: './file');
server.on('request', function (req, res) {
buffet(req, res, function () {
buffet.notFound(req, res);
});
});
server.listen(3000, function () {
console.log('test server running on port 3000');
});
Take a look on that link.
You need only to install express module of node js.
var express = require('express');
var app = express();
app.use('/Folder', express.static(__dirname + '/Folder'));
You can access your file like http://hostname/Folder/file.zip
First install node-static server via npm install node-static -g -g is to install it global on your system, then navigate to the directory where your files are located, start the server with static it listens on port 8080, naviaget to the browser and type localhost:8080/yourhtmlfilename.
A simple Static-Server using connect
var connect = require('connect'),
directory = __dirname,
port = 3000;
connect()
.use(connect.logger('dev'))
.use(connect.static(directory))
.listen(port);
console.log('Listening on port ' + port);
See also Using node.js as a simple web server
It isn't on NPM, yet, but I built a simple static server on Express that also allows you to accept form submissions and email them through a transactional email service (Sendgrid for now, Mandrill coming).
https://github.com/jdr0dn3y/nodejs-StatServe
For the benefit of searchers, I liked Jakub g's answer, but wanted a little error handling. Obviously it's best to handle errors properly, but this should help prevent a site stopping if an error occurs. Code below:
var http = require('http');
var express = require('express');
process.on('uncaughtException', function(err) {
console.log(err);
});
var server = express();
server.use(express.static(__dirname));
var port = 10001;
server.listen(port, function() {
console.log('listening on port ' + port);
//var err = new Error('This error won't break the application...')
//throw err
});
For dev work you can use (express 4)
https://github.com/appsmatics/simple-httpserver.git
I use Houston at work and for personal projects, it works well for me.
https://github.com/alejandro/Houston
const http = require('http');
const fs = require('fs');
const url = require('url');
const path = require('path');
let mimeTypes = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'text/javascript',
'.jpg': 'image/jpeg',
'.png': 'image/png',
'.ico': 'image/x-icon',
'.svg': 'image/svg+xml',
'.eot': 'appliaction/vnd.ms-fontobject',
'.ttf': 'aplication/font-sfnt'
};
http.createServer(function (request, response) {
let pathName = url.parse(request.url).path;
if(pathName === '/'){
pathName = '/index.html';
}
pathName = pathName.substring(1, pathName.length);
let extName = path.extName(pathName);
let staticFiles = `${__dirname}/template/${pathName}`;
if(extName =='.jpg' || extName == '.png' || extName == '.ico' || extName == '.eot' || extName == '.ttf' || extName == '.svg')
{
let file = fr.readFileSync(staticFiles);
res.writeHead(200, {'Content-Type': mimeTypes[extname]});
res.write(file, 'binary');
res.end();
}else {
fs.readFile(staticFiles, 'utf8', function (err, data) {
if(!err){
res.writeHead(200, {'Content-Type': mimeTypes[extname]});
res.end(data);
}else {
res.writeHead(404, {'Content-Type': 'text/html;charset=utf8'});
res.write(`<strong>${staticFiles}</strong>File is not found.`);
}
res.end();
});
}
}).listen(8081);
If you are intrested in ultra-light http server without any prerequisites
you should have a look at: mongoose
You also asked why requests are dropping - not sure what's the specific reason on your case, but in overall you better server static content using dedicated middleware (nginx, S3, CDN) because Node is really not optimized for this networking pattern. See further explanation here (bullet 13):
http://goldbergyoni.com/checklist-best-practice-of-node-js-in-production/
Related
Simple Server Node.js return html page
I am trying to run a local server on Node.js that returns a simple html page. The difficulty for me at this point is understanding how to make the file system handle function correctly.. I am looking for the right code to use when the /recipe extension is called in the browser. I get the error "no such file or directory", while the path they specify is correct. There is a file in there with the correct name.. Do I have to manually add "fs" in npm? Is there another mistake in my code? Am I forgetting something? I have the following code: // strict mode catches javascript errors better.. "use strict"; // localhost port on which you can access the application in DEV // http status codes accesses npm package that contains main API status codes // fs is the file system handler to handle the html files const port = 3000, http = require("http"), httpStatus = require("http-status-codes"), app = http.createServer(), fs = require("fs"); // set up route mapping for html file const routeResponseMap = { "/recipe": "view/recipe.html", "/index": "<h2>this is the index page</h2>" }; // need to open your browser localhost:port for the request to be made.. app.on("request", (request,response) => { response.writeHead(httpStatus.OK, {"Content-Type": "text/html"}); if(routeResponseMap[request.url]){ response.end(routeResponseMap[request.url]); if(routesResponse[request.url]){ // the error is here, file does not get read // WHAT CODE DO I NEED HERE? fs.readFile(routesResponse[request.url]), (error, data) => { response.write(data); response.end(); } console.log("route in mapping"); } else{ response.end("<h3>Sorry not found</h3>"); } }) app.listen(port); console.log("The server has started and is listening on port " + port);
"Dockerized" Node.js Application Not Responding to Host
I am trying to "Dockerize" a rather large, complicated Node.js application, which is roughly structured like so: Nebula [root directory of the project; runs the Node.js application] |__CosmosD3 [directory that contains all HTML and JS files] |__Nebula-Pipeline [directory that contains most Python files that do all the heavy computations] Our standard installation process for this project is rather complicated due to all the interconnected pieces that all must work together flawlessly to enable our front end JS files to communicate with our back end Python scripts. For Linux/Unix systems, this is the rough process (with commands run from within the Nebula directory): Install Java. (Just about any version should do; we have a single Java file that needs to be run for a particular interaction in the front end) Install Python 2.7 and pip Run pip install --upgrade pip to ensure the latest pip is being used Install Node.js, npm, and zmq using sudo apt-get install libzmq-dev npm nodejs-legacy Run npm install to install our Node.js package dependencies Run pip install -e ./Nebula-Pipeline to install all Python dependencies Pray that everything has gone smoothly and run the application with npm start. The default port is 8081, so the application should be accessible through localhost:8081. A very similar project to this one has already been "Dockerized." By tweaking the Dockerfile for the other project to more closely correspond to the steps above, this is the Dockerfile I've created: FROM ubuntu:16.04 RUN mkdir /www WORKDIR /www RUN apt-get update RUN apt-get install -y libzmq-dev npm nodejs-legacy python python-pip RUN apt-get update && \ apt-get install -y openjdk-8-jdk && \ apt-get install -y ant && \ apt-get clean; # Fix certificate issues, found as of # https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/983302 RUN apt-get update && \ apt-get install ca-certificates-java && \ apt-get clean && \ update-ca-certificates -f; # Setup JAVA_HOME, this is useful for docker commandline ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ RUN export JAVA_HOME ##COPY ./lib/ /opt/lib RUN pip install --upgrade pip COPY ./Nebula /www RUN ls -a /www RUN npm install RUN pip install -e /www/Nebula-Pipeline EXPOSE 8081 CMD ["npm", "start"] When I run this Dockerfile with docker build -t nebulaserver, it appears that the image is created successfully. When I run the image with docker run -p 8081:8081 nebulaserver, I get the following printout that seems to indicate that everything is actually working properly. (Note that the "PORT: 8081" printout is a confirmation of the port that the Node.js app is using.) Michelles-MacBook-Pro-8$ docker run -p 8081:8081 nebulaserver > Nebula#0.0.1 start /www > node app.js PORT: 8081 However, when I subsequently try to connect to localhost:8081, I don't get any kind of response. Additionally, I expect to see additional printouts from my Node.js server when it receives a request for one of the HTML pages. I don't see any of these printouts either. It's as if the port forwarding is not working properly. Based on everything I've read, I should be doing things correctly, but I've never used Docker before, so perhaps I'm missing something? Anyone have any idea what I might be doing wrong? EDIT: Here's my app.js file, in case that helps figure out what's going on... /*Import packages required in package.json */ /*Add these packages from the ../node_modules path*/ var express = require('express');//A lightweight nodejs web framework var path = require('path');//Ability to join filepaths to filenames. var favicon = require('serve-favicon');//Set prefered icon in browser URL bar. Unused? var logger = require('morgan');//HTTP request logger. Unused? var cookieParser = require('cookie-parser');//Stores cookies in req.cookies var bodyParser = require('body-parser');//Middleware parser for incoming request bodies, /* REST API routes */ var routes = require('./routes/index');//Points to /routes/index.js. Currently, index.js points to CosmosD3/CosmosD3.html /* Connect to the databases */ //var mongo = require('mongodb'); //var monk = require('monk'); //var db = monk('localhost:27017/nodetest'); //var datasets = monk('localhost:27017/datasets'); /* The HTTP request handler */ var app = express();//Creates app from express class. (Baseline famework for an app. No web functionality). var debug = require('debug')('Nebula:server');//Require the debug module. Pass it scoping 'Nebula:server' var http = require('http').Server(app);//Create an http server on top of app. /* The Socket.io WebSocket module */ var io = require('socket.io')(http);//Create an io/websocket on top of http object. /* Our custom Nebula module handles the WebSocket synchronization */ var nebula = require('./nebula')(io);//Creates nebula layer on top of io. /* Set the port we want to run on */ var port = process.env.PORT || 8080; //app.set('port', port); var host = '0.0.0.0'; app.listen(port, host); console.log(`Running on http://${host}:${port}`); /* view engine setup, currently not used */ app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); /* Expose everything in public/ through our web server */ app.use(express.static(path.join(__dirname, 'public'))); app.use("/cosmos", express.static(path.join(__dirname, 'CosmosD3'))); // Make our db accessible to our router //app.use(function(req, res, next){ // req.db = db; // req.datasets = datasets; // next(); //}); /* Initiate the REST API */ app.use('/', routes); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = (typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port); // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = http.address(); var bind = (typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port); debug('Listening on ' + bind); } /** * Listen on provided port, on all network interfaces. */ http.listen(port); http.on('error', onError); http.on('listening', onListening);
I have had this problem before and (as mentioned by #davidmaze in his comment) I had to change the host that my app was listening on. In my case, it was that I was using the Express framework, which (despite the docs implying otherwise) was listening only for localhost (127.0.0.1), and I needed it to listen to 0.0.0.0. See lines 58-66 (which make up the 2nd code block in the Create the Node.js app section of the Dockerizing a Node.js web app example) for where they explicitly tell express to listen for 0.0.0.0.
I finally figured it out!! After a ton of digging around, I discovered that the default IP for Docker applications is http://192.168.99.100 as opposed to http://localhost. I got the answer from here: https://forums.docker.com/t/docker-running-host-but-not-accessible/44082/13
On a MAC, I had to put in the port in two spots: in the Dockerfile I needed to put in: EXPOSE 5000 5010 5011 before the CMD line (second to last line) and it exposes 3 ports In docker-compose.yml (I have two dockers) I need to put in at the app part: ports: "5000:5000" "5010:5010" "5011:5011"
Issues Getting Highcharts Export Server Running Under iisnode
I am working on trying to set up the Highcharts export server under node.js using iisnode (https://github.com/tjanczuk/iisnode). It basically acts as a pipe between requests to IIS through to node. Great! Only, how do I "install" the highcharts export server so it is using iisnode? I did the instructions on how to install the highcharts-export node module but it is installed under (Windows) AppData\Roaming\npm. How to move or point iisnode to the export server? This export server is run via the following once installed from npm: highcharts-export-server --enableServer 1 So, to get this installed and used in IIS8 + iisnode 1) What is the right directory to install export server locally (on Windows the modules pulled in via npm go to C:\Users\\AppData\Roaming\nmp\ where is the logged in user using npm to install the package)? 2) What is the iisnode configuration necessary for this? I have the iisnode setup and running on our development box and all the examples work. My confusion lies partly with the utter lack of documentation for issnode. All the links I have found just repeat the items listed in the links from the issnode developer with no actual "here is how you take a node app that exists in npm and have it work in issnode." I don't necessarily need my hand held every step of the way. I am just seeing no list of steps to even follow.
install node (if not already installed) install iisnode (if not already installed => https://github.com/tjanczuk/iisnode) verify IIS has iisnode registered as a module create a new Application Pool, set to "No Managed Code" create a new empty web site load the iisnode sample content into it, update the web.config verify you can hit it and it runs and can write it's logs go to the IIS web site folder and run these npm commands npm init /empty npm install --save highcharts-export-server npm install --save tmp add file hcexport.js and reconfigure web.config var fs = require('fs'); var http = require('http'); var path = require("path"); var tmp = require('tmp'); const exporter = require('highcharts-export-server'); http.createServer(function (req, res) { try { if (req.method !== 'POST') { throw "POST Only"; } var body = ''; req.on('data', function (data) { body += data; }); req.on('end', function () { if (body === '') { throw "Empty body"; } var tempFile = tmp.fileSync({discardDescriptor: true, postfix: ".svg", dir: process.cwd()}); var input = JSON.parse(body); input.outfile = path.basename(tempFile.name); exporter.initPool(); exporter.export(input, function (err, exres) { if (err) { throw "Export failed"; } var filename = path.join(process.cwd(), exres.filename); exporter.killPool(); fs.readFile(filename, function(err, file) { res.writeHead(200, { 'Content-Type': 'image/svg+xml', 'Content-disposition': 'attachment; filename=' + exres.filename }); res.write(file.toString()); res.end(); tempFile.removeCallback(); }); }); }); } catch (err) { console.log({port: process.env.PORT, error: err}); res.writeHead(409, { 'Content-Type': 'text/html' }); res.end(err.message); } }).listen(process.env.PORT); Extend as needed to support the export types you plan to use. The highcharts-export-server uses phantomjs internally and this can run away under some error conditions using up 100% of available CPU, if you see this you can kill it using: Taskkill /IM phantomjs.exe /F
The solution from saukender seems to work, however it seems that it always initializes a new pool of phantom workers every time. If you already have node and issnode setup, another solution is to directly start the highcharts export server and not call the export function manually. This seems to provide a better performance, since it doesn't initialze the worker pool on every request. // app.js const highcharts = require("highcharts-export-server"); highcharts.initPool(); highcharts.startServer(process.env.PORT || 8012); Don't forget to point your web.config to app.js. I found these two resource quite useful during setup: https://www.galaco.me/node-js-on-windows-server-2012/ https://tomasz.janczuk.org/2011/08/hosting-nodejs-applications-in-iis-on.html
Access SFTP from NodeJS
I have a need where i have to open a SFTP connection with a server, copy a file from there to local. To that end, i have tried installing node-sftp module using npm install node-sftp It didnt work out of the box, i had to replace the sftp.js file that was installed by npm with that of github repository here : https://github.com/ajaxorg/node-sftp (npm version was using TTY and github version was using PTY. i am not sure what they are) After start the server and invoking the code, i see this in console. launching: sftp -o Port=22 jash#xxx.63.xxx.49 listening... console just hangs here. I am trying to print all files in the current directory after connection is opened. This is the code var http = require('http'); var Sftp = require('node-sftp'); var port = process.env.PORT || 1337; var msgHandler = function(request, response) { var options = { host:"xxx.63.xxx.49", username:"jash", password:"mypassword", port:22 }; var conn = new Sftp(options,function(err){ console.log(err); }); conn.cd(".", function(err) { console.log(err); conn.ls(".", function(err, res) { console.log(res[0].path); }); }); console.log("listening..."); } http.createServer(msgHandler).listen(port); The credentials are fine, i used them in SecureCRT and was able to login.
The second argument to Sftp() (the function(err)...) is where you want to place your conn.cd(... code. It (said 2nd argument) is a function that gets called once the connection has been established. Make sure to check for err of course.
Using Node.js as a simple web server
I want to run a very simple HTTP server. Every GET request to example.com should get index.html served to it but as a regular HTML page (i.e., same experience as when you read normal web pages). Using the code below, I can read the content of index.html. How do I serve index.html as a regular web page? var http = require('http'); var fs = require('fs'); var index = fs.readFileSync('index.html'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(index); }).listen(9615); One suggestion below is complicated and requires me to write a get line for each resource (CSS, JavaScript, images) file I want to use. How can I serve a single HTML page with some images, CSS and JavaScript?
Simplest Node.js server is just: $ npm install http-server -g Now you can run a server via the following commands: $ cd MyApp $ http-server If you're using NPM 5.2.0 or newer, you can use http-server without installing it with npx. This isn't recommended for use in production but is a great way to quickly get a server running on localhost. $ npx http-server Or, you can try this, which opens your web browser and enables CORS requests: $ http-server -o --cors For more options, check out the documentation for http-server on GitHub, or run: $ http-server --help Lots of other nice features and brain-dead-simple deployment to NodeJitsu. Feature Forks Of course, you can easily top up the features with your own fork. You might find it's already been done in one of the existing 800+ forks of this project: https://github.com/nodeapps/http-server/network Light Server: An Auto Refreshing Alternative A nice alternative to http-server is light-server. It supports file watching and auto-refreshing and many other features. $ npm install -g light-server $ light-server Add to your directory context menu in Windows Explorer reg.exe add HKCR\Directory\shell\LightServer\command /ve /t REG_EXPAND_SZ /f /d "\"C:\nodejs\light-server.cmd\" \"-o\" \"-s\" \"%V\"" Simple JSON REST server If you need to create a simple REST server for a prototype project then json-server might be what you're looking for. Auto Refreshing Editors Most web page editors and IDE tools now include a web server that will watch your source files and auto refresh your web page when they change. I use Live Server with Visual Studio Code. The open source text editor Brackets also includes a NodeJS static web server. Just open any HTML file in Brackets, press "Live Preview" and it starts a static server and opens your browser at the page. The browser will auto refresh whenever you edit and save the HTML file. This especially useful when testing adaptive web sites. Open your HTML page on multiple browsers/window sizes/devices. Save your HTML page and instantly see if your adaptive stuff is working as they all auto refresh. Web / SPA / PWA / Mobile / Desktop / Browser Ext Web Developers Some SPA frameworks include a built in version of the Webpack DevServer that can detect source file changes and trigger an incremental rebuild and patch (called hot reloading) of your SPA or PWA web app. Here's a few popular SPA frameworks that can do this. VueJS Developers For VueJS developers, a favorite is Quasar Framework that includes the Webpack DevServer out of the box with switches to support server-side rendering (SSR) and proxy rules to cure your CORS issues. It includes a large number of optimized components designed to adapt for both Mobile and Desktop. These allows you to build one app for ALL platforms (SPA, SPA+SSR, PWA, PWA+SSR, Cordova and Capacitor Mobile AppStore apps, Electron Desktop Node+VueJS apps and even Browser extensions). Another popular one is NuxtJS that also supports static HTML/CSS code generation as well as SSR or no-SSR build modes with plugins for other UI component suites. React Framework Developers ReactJS developers can also setup hot reloading. Cordova/Capacitor + Ionic Framework Developers Iconic is a mobile only hybrid component framework that now supports VueJS, React and Angular development. A local server with auto refresh features is baked into the ionic tool. Just run ionic serve from your app folder. Even better ... ionic serve --lab to view auto-refreshing side by side views of both iOS and Android.
Note: This answer is from 2011. However, it is still valid. You can use Connect and ServeStatic with Node.js for this: Install connect and serve-static with NPM $ npm install connect serve-static Create server.js file with this content: var connect = require('connect'); var serveStatic = require('serve-static'); connect() .use(serveStatic(__dirname)) .listen(8080, () => console.log('Server running on 8080...')); Run with Node.js $ node server.js You can now go to http://localhost:8080/yourfile.html
Check out this gist. I'm reproducing it here for reference, but the gist has been regularly updated. Node.JS static file web server. Put it in your path to fire up servers in any directory, takes an optional port argument. var http = require("http"), url = require("url"), path = require("path"), fs = require("fs"), port = process.argv[2] || 8888; http.createServer(function(request, response) { var uri = url.parse(request.url).pathname , filename = path.join(process.cwd(), uri); fs.exists(filename, function(exists) { if(!exists) { response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); response.end(); return; } if (fs.statSync(filename).isDirectory()) filename += '/index.html'; fs.readFile(filename, "binary", function(err, file) { if(err) { response.writeHead(500, {"Content-Type": "text/plain"}); response.write(err + "\n"); response.end(); return; } response.writeHead(200); response.write(file, "binary"); response.end(); }); }); }).listen(parseInt(port, 10)); console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown"); Update The gist does handle css and js files. I've used it myself. Using read/write in "binary" mode isn't a problem. That just means that the file isn't interpreted as text by the file library and is unrelated to content-type returned in the response. The problem with your code is you're always returning a content-type of "text/plain". The above code does not return any content-type, but if you're just using it for HTML, CSS, and JS, a browser can infer those just fine. No content-type is better than a wrong one. Normally the content-type is a configuration of your web server. So I'm sorry if this doesn't solve your problem, but it worked for me as a simple development server and thought it might help some other people. If you do need correct content-types in the response, you either need to explicitly define them as joeytwiddle has or use a library like Connect that has sensible defaults. The nice thing about this is that it's simple and self-contained (no dependencies). But I do feel your issue. So here is the combined solution. var http = require("http"), url = require("url"), path = require("path"), fs = require("fs") port = process.argv[2] || 8888; http.createServer(function(request, response) { var uri = url.parse(request.url).pathname , filename = path.join(process.cwd(), uri); var contentTypesByExtension = { '.html': "text/html", '.css': "text/css", '.js': "text/javascript" }; fs.exists(filename, function(exists) { if(!exists) { response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); response.end(); return; } if (fs.statSync(filename).isDirectory()) filename += '/index.html'; fs.readFile(filename, "binary", function(err, file) { if(err) { response.writeHead(500, {"Content-Type": "text/plain"}); response.write(err + "\n"); response.end(); return; } var headers = {}; var contentType = contentTypesByExtension[path.extname(filename)]; if (contentType) headers["Content-Type"] = contentType; response.writeHead(200, headers); response.write(file, "binary"); response.end(); }); }); }).listen(parseInt(port, 10)); console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown");
You don't need express. You don't need connect. Node.js does http NATIVELY. All you need to do is return a file dependent on the request: var http = require('http') var url = require('url') var fs = require('fs') http.createServer(function (request, response) { var requestUrl = url.parse(request.url) response.writeHead(200) fs.createReadStream(requestUrl.pathname).pipe(response) // do NOT use fs's sync methods ANYWHERE on production (e.g readFileSync) }).listen(9615) A more full example that ensures requests can't access files underneath a base-directory, and does proper error handling: var http = require('http') var url = require('url') var fs = require('fs') var path = require('path') var baseDirectory = __dirname // or whatever base directory you want var port = 9615 http.createServer(function (request, response) { try { var requestUrl = url.parse(request.url) // need to use path.normalize so people can't access directories underneath baseDirectory var fsPath = baseDirectory+path.normalize(requestUrl.pathname) var fileStream = fs.createReadStream(fsPath) fileStream.pipe(response) fileStream.on('open', function() { response.writeHead(200) }) fileStream.on('error',function(e) { response.writeHead(404) // assume the file doesn't exist response.end() }) } catch(e) { response.writeHead(500) response.end() // end the response so browsers don't hang console.log(e.stack) } }).listen(port) console.log("listening on port "+port)
I think the part you're missing right now is that you're sending: Content-Type: text/plain If you want a web browser to render the HTML, you should change this to: Content-Type: text/html
Step1 (inside command prompt [I hope you cd TO YOUR FOLDER]) : npm install express Step 2: Create a file server.js var fs = require("fs"); var host = "127.0.0.1"; var port = 1337; var express = require("express"); var app = express(); app.use(express.static(__dirname + "/public")); //use static files in ROOT/public folder app.get("/", function(request, response){ //root dir response.send("Hello!!"); }); app.listen(port, host); Please note, you should add WATCHFILE (or use nodemon) too. Above code is only for a simple connection server. STEP 3: node server.js or nodemon server.js There is now more easy method if you just want host simple HTTP server. npm install -g http-server and open our directory and type http-server https://www.npmjs.org/package/http-server
The fast way: var express = require('express'); var app = express(); app.use('/', express.static(__dirname + '/../public')); // ← adjust app.listen(3000, function() { console.log('listening'); }); Your way: var http = require('http'); var fs = require('fs'); http.createServer(function (req, res) { console.dir(req.url); // will get you '/' or 'index.html' or 'css/styles.css' ... // • you need to isolate extension // • have a small mimetype lookup array/object // • only there and then reading the file // • delivering it after setting the right content type res.writeHead(200, {'Content-Type': 'text/html'}); res.end('ok'); }).listen(3001);
Rather than dealing with a switch statement, I think it's neater to lookup the content type from a dictionary: var contentTypesByExtension = { 'html': "text/html", 'js': "text/javascript" }; ... var contentType = contentTypesByExtension[fileExtension] || 'text/plain';
You can just type those in your shell npx serve Repo: https://github.com/zeit/serve.
You don't need to use any npm modules to run a simple server, there's a very tiny library called "npm Free Server" for Node: 50 lines of code Outputs if you are requesting a file or a folder Gives it a red or green color if it failed or worked Less than 1KB in size (minified) Fully commented so you can tweak it as needed npm-free-server (on GitHub)
This is basically an updated version of the accepted answer for connect version 3: var connect = require('connect'); var serveStatic = require('serve-static'); var app = connect(); app.use(serveStatic(__dirname, {'index': ['index.html']})); app.listen(3000); I also added a default option so that index.html is served as a default.
if you have node installed on you PC probably you have the NPM, if you don't need NodeJS stuff, you can use the serve package for this: 1 - Install the package on your PC: npm install -g serve 2 - Serve your static folder: serve <path> d:> serve d:\StaticSite It will show you which port your static folder is being served, just navigate to the host like: http://localhost:3000
I found a interesting library on npm that might be of some use to you. It's called mime(npm install mime or https://github.com/broofa/node-mime) and it can determine the mime type of a file. Here's an example of a webserver I wrote using it: var mime = require("mime"),http = require("http"),fs = require("fs"); http.createServer(function (req, resp) { path = unescape(__dirname + req.url) var code = 200 if(fs.existsSync(path)) { if(fs.lstatSync(path).isDirectory()) { if(fs.existsSync(path+"index.html")) { path += "index.html" } else { code = 403 resp.writeHead(code, {"Content-Type": "text/plain"}); resp.end(code+" "+http.STATUS_CODES[code]+" "+req.url); } } resp.writeHead(code, {"Content-Type": mime.lookup(path)}) fs.readFile(path, function (e, r) { resp.end(r); }) } else { code = 404 resp.writeHead(code, {"Content-Type":"text/plain"}); resp.end(code+" "+http.STATUS_CODES[code]+" "+req.url); } console.log("GET "+code+" "+http.STATUS_CODES[code]+" "+req.url) }).listen(9000,"localhost"); console.log("Listening at http://localhost:9000") This will serve any regular text or image file (.html, .css, .js, .pdf, .jpg, .png, .m4a and .mp3 are the extensions I've tested, but it theory it should work for everything) Developer Notes Here is an example of output that I got with it: Listening at http://localhost:9000 GET 200 OK /cloud GET 404 Not Found /cloud/favicon.ico GET 200 OK /cloud/icon.png GET 200 OK / GET 200 OK /501.png GET 200 OK /cloud/manifest.json GET 200 OK /config.log GET 200 OK /export1.png GET 200 OK /Chrome3DGlasses.pdf GET 200 OK /cloud GET 200 OK /-1 GET 200 OK /Delta-Vs_for_inner_Solar_System.svg Notice the unescape function in the path construction. This is to allow for filenames with spaces and encoded characters.
Edit: Node.js sample app Node Chat has the functionality you want. In it's README.textfile 3. Step is what you are looking for. step1 create a server that responds with hello world on port 8002 step2 create an index.html and serve it step3 introduce util.js change the logic so that any static file is served show 404 in case no file is found step4 add jquery-1.4.2.js add client.js change index.html to prompt user for nickname Here is the server.js Here is the util.js
var http = require('http'); var fs = require('fs'); var index = fs.readFileSync('index.html'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); // change the to 'text/plain' to 'text/html' it will work as your index page res.end(index); }).listen(9615); I think you where searching for this. In your index.html, simply fill it with normal html code - whatever you want to render on it, like: <html> <h1>Hello world</h1> </html>
The way I do it is to first of all install node static server globally via npm install node-static -g then navigate to the directory that contains your html files and start the static server with static. Go to the browser and type localhost:8080/"yourHtmlFile".
Basically copying the accepted answer, but avoiding creating a js file. $ node > var connect = require('connect'); connect().use(static('.')).listen(8000); Found it very convinient. Update As of latest version of Express, serve-static has become a separate middleware. Use this to serve: require('http').createServer(require('serve-static')('.')).listen(3000) Install serve-static first.
I use below code to start a simple web server which render default html file if no file mentioned in Url. var http = require('http'), fs = require('fs'), url = require('url'), rootFolder = '/views/', defaultFileName = '/views/5 Tips on improving Programming Logic Geek Files.htm'; http.createServer(function(req, res){ var fileName = url.parse(req.url).pathname; // If no file name in Url, use default file name fileName = (fileName == "/") ? defaultFileName : rootFolder + fileName; fs.readFile(__dirname + decodeURIComponent(fileName), 'binary',function(err, content){ if (content != null && content != '' ){ res.writeHead(200,{'Content-Length':content.length}); res.write(content); } res.end(); }); }).listen(8800); It will render all js, css and image file, along with all html content. Agree on statement "No content-type is better than a wrong one"
from w3schools it is pretty easy to create a node server to serve any file that is requested, and you dont need to install any packages for it var http = require('http'); var url = require('url'); var fs = require('fs'); http.createServer(function (req, res) { var q = url.parse(req.url, true); var filename = "." + q.pathname; fs.readFile(filename, function(err, data) { if (err) { res.writeHead(404, {'Content-Type': 'text/html'}); return res.end("404 Not Found"); } res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); return res.end(); }); }).listen(8080); http://localhost:8080/file.html will serve file.html from disk
var http = require('http'); var fs = require('fs'); var index = fs.readFileSync('index.html'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'html'}); res.end(index); }).listen(9615); //Just Change The CONTENT TYPE to 'html'
I'm not sure if this is exactly what you wanted, however, you can try changing: {'Content-Type': 'text/plain'} to this: {'Content-Type': 'text/html'} This will have the browser client display the file as html instead of plain text.
Express function sendFile does exactly what you need, and since you want web server functionality from node, express comes as natural choice and then serving static files becomes as easy as : res.sendFile('/path_to_your/index.html') read more here : https://expressjs.com/en/api.html#res.sendFile A small example with express web server for node: var express = require('express'); var app = express(); var path = require('path'); app.get('/', function(req, res) { res.sendFile(path.join(__dirname + '/index.html')); }); app.listen(8080); run this, and navigate to http://localhost:8080 To expand on this to allow you to serve static files like css and images, here's another example : var express = require('express'); var app = express(); var path = require('path'); app.use(express.static(__dirname + '/css')); app.get('/', function(req, res) { res.sendFile(path.join(__dirname + '/index.html')); }); app.listen(8080); so create a subfolder called css, put your static content in it, and it will be available to your index.html for easy reference like : <link type="text/css" rel="stylesheet" href="/css/style.css" /> Notice relative path in href! voila!
A slightly more verbose express 4.x version but that provides directory listing, compression, caching and requests logging in a minimal number of lines var express = require('express'); var compress = require('compression'); var directory = require('serve-index'); var morgan = require('morgan'); //logging for express var app = express(); var oneDay = 86400000; app.use(compress()); app.use(morgan()); app.use(express.static('filesdir', { maxAge: oneDay })); app.use(directory('filesdir', {'icons': true})) app.listen(process.env.PORT || 8000); console.log("Ready To serve files !")
Crazy amount of complicated answers here. If you don't intend to process nodeJS files/database but just want to serve static html/css/js/images as your question suggest then simply install the pushstate-server module or similar; Here's a "one liner" that will create and launch a mini site. Simply paste that entire block in your terminal in the appropriate directory. mkdir mysite; \ cd mysite; \ npm install pushstate-server --save; \ mkdir app; \ touch app/index.html; \ echo '<h1>Hello World</h1>' > app/index.html; \ touch server.js; \ echo "var server = require('pushstate-server');server.start({ port: 3000, directory: './app' });" > server.js; \ node server.js Open browser and go to http://localhost:3000. Done. The server will use the app dir as the root to serve files from. To add additional assets just place them inside that directory.
There are already some great solutions for a simple nodejs server. There is a one more solution if you need live-reloading as you made changes to your files. npm install lite-server -g navigate your directory and do lite-server it will open browser for you with live-reloading.
The simpler version which I've came across is as following. For education purposes, it is best, because it does not use any abstract libraries. var http = require('http'), url = require('url'), path = require('path'), fs = require('fs'); var mimeTypes = { "html": "text/html", "mp3":"audio/mpeg", "mp4":"video/mp4", "jpeg": "image/jpeg", "jpg": "image/jpeg", "png": "image/png", "js": "text/javascript", "css": "text/css"}; http.createServer(function(req, res) { var uri = url.parse(req.url).pathname; var filename = path.join(process.cwd(), uri); fs.exists(filename, function(exists) { if(!exists) { console.log("not exists: " + filename); res.writeHead(200, {'Content-Type': 'text/plain'}); res.write('404 Not Found\n'); res.end(); return; } var mimeType = mimeTypes[path.extname(filename).split(".")[1]]; res.writeHead(200, {'Content-Type':mimeType}); var fileStream = fs.createReadStream(filename); fileStream.pipe(res); }); //end path.exists }).listen(1337); Now go to browser and open following: http://127.0.0.1/image.jpg Here image.jpg should be in same directory as this file. Hope this helps someone :)
local-web-server is definitely worth a look! Here's an excerpt from the readme: local-web-server A lean, modular web server for rapid full-stack development. Supports HTTP, HTTPS and HTTP2. Small and 100% personalisable. Load and use only the behaviour required by your project. Attach a custom view to personalise how activity is visualised. Programmatic and command-line interfaces. Use this tool to: Build any type of front-end web application (static, dynamic, Single Page App, Progessive Web App, React etc). Prototype a back-end service (REST API, microservice, websocket, Server Sent Events service etc). Monitor activity, analyse performance, experiment with caching strategy etc. Local-web-server is a distribution of lws bundled with a "starter pack" of useful middleware. Synopsis This package installs the ws command-line tool (take a look at the usage guide). Static web site Running ws without any arguments will host the current directory as a static web site. Navigating to the server will render a directory listing or your index.html, if that file exists. $ ws Listening on http://mbp.local:8000, http://127.0.0.1:8000, http://192.168.0.100:8000 Static files tutorial. This clip demonstrates static hosting plus a couple of log output formats - dev and stats. Single Page Application Serving a Single Page Application (an app with client-side routing, e.g. a React or Angular app) is as trivial as specifying the name of your single page: $ ws --spa index.html With a static site, requests for typical SPA paths (e.g. /user/1, /login) would return 404 Not Found as a file at that location does not exist. However, by marking index.html as the SPA you create this rule: If a static file is requested (e.g. /css/style.css) then serve it, if not (e.g. /login) then serve the specified SPA and handle the route client-side. SPA tutorial. URL rewriting and proxied requests Another common use case is to forward certain requests to a remote server. The following command proxies blog post requests from any path beginning with /posts/ to https://jsonplaceholder.typicode.com/posts/. For example, a request for /posts/1 would be proxied to https://jsonplaceholder.typicode.com/posts/1. $ ws --rewrite '/posts/(.*) -> https://jsonplaceholder.typicode.com/posts/$1' Rewrite tutorial. This clip demonstrates the above plus use of --static.extensions to specify a default file extension and --verbose to monitor activity. HTTPS and HTTP2 For HTTPS or HTTP2, pass the --https or --http2 flags respectively. See the wiki for further configuration options and a guide on how to get the "green padlock" in your browser. $ lws --http2 Listening at https://mba4.local:8000, https://127.0.0.1:8000, https://192.168.0.200:8000
Most of the answers above describe very nicely how contents are being served. What I was looking as additional was listing of the directory so that other contents of the directory can be browsed. Here is my solution for further readers: 'use strict'; var finalhandler = require('finalhandler'); var http = require('http'); var serveIndex = require('serve-index'); var serveStatic = require('serve-static'); var appRootDir = require('app-root-dir').get(); var log = require(appRootDir + '/log/bunyan.js'); var PORT = process.env.port || 8097; // Serve directory indexes for reports folder (with icons) var index = serveIndex('reports/', {'icons': true}); // Serve up files under the folder var serve = serveStatic('reports/'); // Create server var server = http.createServer(function onRequest(req, res){ var done = finalhandler(req, res); serve(req, res, function onNext(err) { if (err) return done(err); index(req, res, done); }) }); server.listen(PORT, log.info('Server listening on: ', PORT));
This is one of the fastest solutions i use to quickly see web pages sudo npm install ripple-emulator -g From then on just enter the directory of your html files and run ripple emulate then change the device to Nexus 7 landscape.
Node.js webserver from scratch No 3rd-party frameworks; Allows query string; Adds trailing slash; Handles 404 Create a public_html subfolder and place all of your content in it. Gist: https://gist.github.com/veganaize/fc3b9aa393ca688a284c54caf43a3fc3 var fs = require('fs'); require('http').createServer(function(request, response) { var path = 'public_html'+ request.url.slice(0, (request.url.indexOf('?')+1 || request.url.length+1) - 1); fs.stat(path, function(bad_path, path_stat) { if (bad_path) respond(404); else if (path_stat.isDirectory() && path.slice(-1) !== '/') { response.setHeader('Location', path.slice(11)+'/'); respond(301); } else fs.readFile(path.slice(-1)==='/' ? path+'index.html' : path, function(bad_file, file_content) { if (bad_file) respond(404); else respond(200, file_content); }); }); function respond(status, content) { response.statusCode = status; response.end(content); } }).listen(80, function(){console.log('Server running on port 80...')});