Home > Blockchain >  CSS style not applied in HTML page served by Node server (without express)
CSS style not applied in HTML page served by Node server (without express)

Time:12-23

I'm sending this HTML file :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <p>Home</p>
</body>

Which refers to this simple CSS file :

p {
    color: blue
}

Using this simple piece of NodeJS code :

require("http").createServer((request, response) => {
    response.setHeader("Content-type", "text/html")
    response.setHeader("Access-Control-Allow-Origin", "*")
    response.statusCode = 200
    response.end(require("fs").readFilSync("index.html", "utf8"))
}).listen(port)

It works just fine except that the style is not applied to the page in Chrome (the text is not blue).

Why is that? Do I have to send the css file aswell? Or do I have to edit the content of the HTML file and to add the style in a <style> tag before sending it?

I'm not using express because I'm practicing raw web dev. (Except for Node)

CodePudding user response:

I am not that great guy in CORS but,

No browser or any client will receive any files or data from your server running if you didn't handle a special request handler for this action.

Which means, you must set a special request for the style.css file so when the browser tries to get this file via a new request, it can get it.

You may wonder, what if I have many many style, script, media, font files that I connected them with my html, and I need to serve them all, here you can put them in one directory, and then set a specific handler that get the first part then match it with the folder of your public files, and then use the path in the end of your request url to find a file inside this public folder, so you can get any file inside that folder easily.

And I know that you may say that you are using response.setHeader("Access-Control-Allow-Origin", "*") and from my knowledge about CORS this is used to leave other servers request your own files, and this will not be done if you didn't handle some requests for these files two.


Much talking!

Let's get to work.

Just put your css file and any other static files like styles | scripts | media | fonts in one folder, let's call it public

And now you need to handle a specific request for any static file, and get it from this folder, so, you project structure will be like that:

  • root/:

    • index.js

    • index.html

    • public/

      • style.css

Now you html and css files are the same, the only change is the path of the style.css file, which moved inside public/ directory.

But your index.js which is the server file will be like that:

let http = require("http")
let fs = require("fs")

let server = http.createServer((req, res) => {
    let url = req.url    // get the url of the request
    if( url.split("/")[1] === "public" ) {
        handlePublic(url, req, res)    // run seperated code if the request contanis public/ in the first of it
    }
    else {
        // here the normal code for all other non public requests
        let html = fs.readFileSync("./index.html")
        res.setHeader("Content-type", "text/html")
        res.statusCode = 200
        res.end(html)
    }
})

function handlePublic(url, req, res) {
    let file = fs.readFileSync("./"   url)  // which will send any file from public/
    res.end( file )
}

server.listen( 3000 )

and now, any file you put in the public folder, and try to access via an http request with a url start with public/ will be send to the client correctly, but all others outside the public directory is save from requests that you didn't handle yet.


I hope I managed to help.

CodePudding user response:

This issue is happening because your server is only serving HTML files for each request. So when the browser asks for a CSS file from your server, it doesn't get a response.

As a solution, you should modify your server to serve a CSS file when it receives an HTTP request that ends with .css(which asks for a CSS file).

const fs = require("fs");
const path = require("path");

port = 3000;
require("http")
  .createServer((request, response) => {
    if (request.url === "/") {
      response.setHeader("Content-type", "text/html");
      response.setHeader("Access-Control-Allow-Origin", "*");
      response.statusCode = 200;
      response.end(require("fs").readFileSync("index.html", "utf8"));
    }
    else if (request.url.match(".css$")) {
      const cssPath = path.join(__dirname, request.url);
      const fileStream = fs.createReadStream(cssPath, "UTF-8");
      response.writeHead(200, { "Content-Type": "text/css" });
      fileStream.pipe(response);
    }
  })
  .listen(port);

  • Related