I am beginner in the field of node js.No idea how to send simple request from url Like :- http://localhost:9999/xyz/inde.html my file hierarchy is
server.js
xyz(folder)-
|->index.html
And get the html page from my server.Which is running at post 9999
var http = require("http");
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.end();
}
http.createServer(onRequest).listen(9999);
console.log("Server has started.");
I know i can send string(having html template) from node js server and send it in response but how to send file without express and any other external module. Thanks
It's possible to use NodeJS alone. But, you have to write more code that is provided by express or any other framework.
Serve Static Resources using Node-static Module The node-static module is an HTTP static-file server module with built-in caching. First of all, install node-static module using NPM as below. After installing node-static module, you can create static file server in Node. js which serves static files only.
To serve static files such as images, CSS files, and JavaScript files, etc we use the built-in middleware in node.
Express offers a built-in middleware to serve your static files and modularizes content within a client-side directory in one line of code.
const http = require('http');
const fs = require("fs");
const path = require("path");
function send404(response){
response.writeHead(404, {'Content-Type': 'text/plain'});
response.write('Error 404: Resource not found.');
response.end();
}
const mimeLookup = {
'.js': 'application/javascript',
'.html': 'text/html'
};
const server = http.createServer((req, res) => {
if(req.method == 'GET'){
let fileurl;
if(req.url == '/'){
fileurl = 'index.html';
}else{
fileurl = req.url;
}
let filepath = path.resolve('./' + fileurl);
let fileExt = path.extname(filepath);
let mimeType = mimeLookup[fileExt];
if(!mimeType) {
send404(res);
return;
}
fs.exists(filepath, (exists) => {
if(!exists){
send404(res);
return;
}
res.writeHead(200, {'Content-Type': mimeType});
fs.createReadStream(filepath).pipe(res);
});
}
}).listen(3000);
console.log("Server running at port 3000");
Heads up for anyone attempting to serve static files without Express or any other framework:
There is no benefit to skipping Express, in terms of performance or productivity. The only exception is to gain an understanding of how the server and client communicate with each other. Frameworks like Express abstract away all of those complexities, and beginners may not fully understand how they work.
Here is my approach to serving static files using Node.js only. Actually, the reason I did this is because a coding test I was given stipulated no framework whatsoever.
First, decide what the URL path for those static files should look like. I want mine to be accessible under /assets/
path, such as https://example.com/assets/main.css
, https://example.com/assets/cat.jpg
.
Decide the REGEX for matching those URL. `const assetPattern = /^/assets/[a-zA-Z]+.[a-zA-Z]+/;
The formula above will match urls which contains /assets/[filename].[file extension
.
// ...
const http = require('http')
const server = http.createServer(requestListener).
const path = require('path');
// ...
const requestListener = (req, response) => {
// get the relative url for the request. For example, relative url for a request
// to https://example.com is /.
const { url } = req;
if (url.match(assetPattern)) {
// Inside the project directory, the static files are located under the
// /public/assets directory.
const filePath = `./public/${url}`;
// Get the extension name aka the string after the dot. For example, a url like
// https://example.com/assets/main.css will result in extension name of css.
const extname = String(path.extname(filePath)).toLowerCase();
const mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpg',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.wav': 'audio/wav',
'.mp4': 'video/mp4',
'.woff': 'application/font-woff',
'.ttf': 'application/font-ttf',
'.eot': 'application/vnd.ms-fontobject',
'.otf': 'application/font-otf',
'.wasm': 'application/wasm',
};
const contentType = mimeTypes[extname] || 'application/octet-stream';
staticFileHandler(req, response, filePath, contentType);
}
}
fs
moduleconst fs = require('fs')
// ...
const staticFileHandler = (req, res, filePath, contentType) => {
fs.readFile(filePath, (err, content) => {
if (err) {
res.writeHead(500);
res.end(`Sorry, check with the site admin for error: ${err.code}`)
} else {
res.writeHead(200, { 'Content-Type': contentType }); // indicate the request was successful
res.end(content, 'utf-8');
}
}
}
I don't agree with the assertion in the accepted answer:
"It's ridiculous to attempt to create a node application without npm dependencies"
as having zero dependencies allows you to deploy an app to a system that runs node by just copying the javascript file(s), and without running npm install
.
An example of when I found this useful in real life was writing a public API to compute the amount of income tax a business needs to withold from an employee's pay. You can read all about this fascinating topic here but in essence I had an api that was passed a gross income and returned how that gross income should be split between net income and tax.
I did this with one solitary index.js file, no package.json, and need to npm install
:
index.js:
http = require('http');
url = require('url');
const port = 80; // make this a number over 1024 if you want to run `node` not run `sudo node`
const debug = true;
const httpServer = http.createServer((request, response) => {
response.setHeader('Content-Type', 'application/json');
const parsedUrl = url.parse(request.url, true);
let pathName = parsedUrl.pathname;
if (pathName==='/favicon.ico') {
// chrome calls this to get an icon to display in the tab. I want to ignore these request. They only happen when testing in a browser,
// not when this api is called in production by a non-browser.
if (debug) console.log('Browser requested favicon.ico')
response.end();
} else {
if (debug) console.log('Request on path ' + pathName);
const elements = pathName.split('/');
if (elements.length == 3 && elements[0] === '' && elements[1]==='witholdcalc') {
const grossString = elements[2];
const gross = Number.parseInt(grossString);
if (isNaN(gross)) {
response.writeHead(400).end(JSON.stringify({error:'Gross salary must be an integer. found: ' + grossString}));
} else {
/*
* The computation of the amount to withold is more complicated that this, but it could still be hard coded here:
* For simplicity, I will compute in one line:
*/
const withold = Math.floor((gross<1000)?0:((gross-1000)*.2));
response.writeHead(200).end(JSON.stringify({net: (gross-withold), withold: withold, elements:(debug?elements:undefined)}));
}
} else {
if (debug) console.log('Invalid path was: ' + pathName,elements);
response.writeHead(404).end();
}
}
});
httpServer.listen(port), () => {
console.log(`PAYG listening at http://localhost:${port}`)
}
I then could execute sudo node install.js
on my linux computer, and in a browser, hit http://localhost/witholdcalc/6000
, and it would return {"net":5000,"withold":1000} when debug is set to false.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With