I have just tried to build up a server on localhost to display an html page. All good so far. The problem arises when I try to style my html page with a css file.
Consider that all my file are in the same directory.
If I run node app.js and I go to local host I can see the page but with no css styling…could you please help me?
Thanks
App.js
const http = require('http');
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, '/')));
let {requestListener} = require('./callbackFile.js');
const PORT = process.env.PORT || 4001;
const server = http.createServer(requestListener);
server.listen(PORT);
console.log("");
console.log("express server should be up&running. Please go to http://localhost:"+PORT);
callbackFile.js
const fs = require('fs');
module.exports = {
requestListener: (req, res) => {
fs.readFile('./ws.html', 'utf-8', (err, data) => {
if (err){
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(`${err}`);
res.end();
} else {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
res.end();
}
})
}
}
ws.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title> website page </title>
</head>
<body>
<h1> Web server up & Running </h1>
<h4> Express Server listening on port 4001 </h4>
</body>
</html>
style.css
h1 {
color: "red";
{
The problem here is that you set up your http server to respond to every request with ws.html. I think it will be clearer if I show a solution you instead of telling you.
App.js
const PORT = process.env.PORT || 4001;
const http = require('http');
var express = require('express');
var path = require('path');
var app = express();
let { requestListener } = require('./callbackFile.js');
app.get("/", requestListener);
app.use(express.static(path.join(__dirname, '/')));
const server = http.createServer(app);
server.listen(PORT);
console.log("");
console.log("express server should be up&running. Please go to http://localhost:"+PORT);
style.css
h1 {
color: red;
}
What I am doing here:
Instead of passing the function requestListener to the http.createServer() function, I passed in the express app variable. You will see the reason for this later.
I put the requestListener function in an Express route. What that does is route all requests for the url "/" to the requestListener function. All other routes will be routed to the Express middleware below that.
I removed the quotes from the h1 styling in the style.css file. As #Phix said, CSS colours don't use quotes.
Why this works
As said in the Express 4.x documentation:
The app returned by express() is in fact a JavaScript Function, designed to be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app with the same code base, as the app does not inherit from these (it is simply a callback):
var express = require('express')
var https = require('https')
var http = require('http')
var app = express()
http.createServer(app).listen(80)
https.createServer(options, app).listen(443)
So, I guess you could say that an Express application is basically a convenient way of defining a callback function for a http or https server
Here is the express 4.x documentation if you need it.
https://expressjs.com/en/4x/api.html
Hope this helps :)
Related
I stripped down the problem to the bare minimum, here's the situation:
The most basic index.html possible, with no DOM elements and only one script, located in the same folder:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="script.js"></script>
</body>
</html>
The simplest possible script.js, which is just a console.log statement:
console.log("%cI'm working!", "font: bold 17px arial; color: #3e9;");
a very simple server.js:
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
const PORT = 3000;
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
}).listen(PORT);
console.log(`Listening on port ${PORT}`);
If I run the page locally, i.e. by launching index.html with my web browser, everything works fine, and I see the log in the console. If, instead, I try to launch the server using node server.js, I come across a very weird error in which script.js appears to contain the contents of index.html, resulting in a syntax error.
Here's a screenshot of DevTools for clarity:
What causes this? How can I correctly include the script on my local server?
Your server responses all requests with index.html. You need a routing.
The most basic approach is
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
var script = fs.readFileSync('script.js');
const PORT = 3000;
http.createServer(function (req, res) {
if (req.path.endsWith('script.js')) {
res.writeHead(200, {'Content-Type': 'text/javascript'});
res.end(script);
} else {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
}
}).listen(PORT);
console.log(`Listening on port ${PORT}`);
This should be only the first step to understand the basics. Usually you would use a framework like Express with a routing as described in https://expressjs.com/en/guide/routing.html and serve static files as described in https://expressjs.com/en/starter/static-files.html
An example with Express:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.static(__dirname));
But this will serve all files in your project root. You should restructure your project and move the files for your website into a separate folder, e.g. public:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.static(path.join(__dirname, 'public')));
I have HTML, CSS, and Javascript programs that work perfectly together. I've recently realized that I'm going to need a server to be able to complete some of my functionality. I've created a local Node server using some tutorials. After reading some suggestions, I'm trying to use Express to try to add the HTML, CSS, and Javascript to the Node, which are all in the same folder. The code I have (below) just causes the browser to stay on loading.
const http = require('http');
const fs = require('fs').promises;
const host = 'localhost';
const port = 8000;
var express = require('express');
var path = require('path');
var app = express();
const requestListener = function (req, res) {
app.use(express.static(path.join(__dirname, 'public')));
//res.writeHead(200);
//res.end("My first server!");
};
const server = http.createServer(requestListener);
server.listen(port, host, () => {
console.log(`Server is running on http://${host}:${port}`);
});
you don't need http module if you are using express...
const express = require('express')
const app = express()
// '/' is the url you want to host your site
// 'public' is the folder in which you have the necessary frontend files
// and the main html should be named as 'index.html' inside 'public'
app.use('/', express.static('public'))
app.listen(5000, () => console.log('server on port 5000'))
Try this....
const express = require('express');
const app = express();
const path = require('path');
app.use(express.static(path.join(__dirname,'css'));
app.use('/html',(req,res,next)=>{
res.sendFile(path.join(__dirname,'HTML','text.html');});
app.listen(3000);
I developed examples on Node.js and Express.js arbtrarily. After initiating example.js of each one shown below, I ran into a font differentiation between them. Even I know Express is a framework for Node, I couldn't find anywhere why typography change though.
Node.js:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Express.js:
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
Output For Node.js:
Output For Express.js:
and here is Express.js version handles the same job
Well, no, not entirely. Your "plain Node" example explicitly sets the content-type to "text/plain", but you don't do the same for the Express example, in which case it will default to "text/html".
If the server tells the browser that the response contains HTML, the browser will apply a default CSS stylesheet, which usually includes a body font (something like Times New Roman).
When you use "text/plain", most browsers will render the content in a monospaced font.
I referred to the previously asked question on this but couldnt resolve it. I have Express server installed and trying to run Index.html file through it.
But I am getting 'Cannot GET /' as the response.
Here is the server.js through which I calling the index.html
var express = require('express');
var app = express();
app.get('index.html', function (req, res) {
app.use("/", express.static(__dirname));
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
Thanks in advance!!
When you access a directory on your hosted site, say the root directory of localhost on port 8080, using http://localhost:8080/ for URL, the browser does not send a request for 'index.html` to the server and just uses whatever the server sends back.
It's the express static middleware which in response to a browser request with no filename will check if the folder exists and (by default) return any index.html contained in the folder. So your line of code for routing, app.get('index.html') never executes, and the browser gives you the error message.
Here's a mini static express server if you want to try it.
var express = require('express');
var app = express();
app.use(express.static('../public')); // path to your public directory
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
If you want a simple static, folder-as-server kind of thing, you can do it without express way like "/public":
var fs = require("fs");
var host = "localhost";
var port = 8000;
var express = require("express");
var app = express();
app.use('/', express.static(__dirname));
app.listen(port, host);
I put this in the file express.js, so that is in the same folder than index.html (even associated .js with node.exe). This way the folder is the root of the server.
I have the following server.js running:
module.exports = server;
var express = require('express');
var fs = require('fs');
var server = express.createServer();
var port = 58000;
server.listen(port);
var io = require('socket.io').listen(server);
server.use(express.static('/', __dirname + '/../public'));
server.use(express.logger());
io.on('connection', function(client){
console.log('new client connected ' + client);
client.on('message', function(){
console.log('client wants something');
});
});
Simple express.static server for files in a /public subfolder, plus socket.io functionality. With this setup, any request for the 'socket.io.js' file fails, i.e.
http://localhost:58000/socket.io/socket.io.js
returns a 404 error (file not found). Static file server works correctly. If I simply use the 'http' module instead of 'express' (commenting out express.static and express.logger lines) socket.io.js is served correctly. How can I combine both functionalities?
Express 3.0.0 (lastest) change its API.
Here is a question very similar to yours that delivers the response.
var express = require('express')
, http = require('http');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
...
server.listen(8000);
Make sure you have the last versions of express.js and of socket.io.js.
My side it's working great with
express#2.5.8
socket.io#0.8.5
node#0.6.5
Otherwise, a solution can be to call var io = require('socket.io').listen(server); after your server.use