1
const express = require('express');
const path = require('path');
const app = express();

// Use static folder middleware
app.use(express.static(path.join(__dirname , "public")));

// Get 
app.get("/" , (req , res)=>{
  res.sendFile(`${__dirname}/index.html`);
});

// Listen
app.listen(3000 , ()=>{
   console.log('server running on port 3000');  
});

Folder structure

Root
 -index.html
 -app.js
  public
    -css
      -index.css
    -images
      -image.png

In the index.html page The index.css file and the image.png are linked. However, Those two are not being server as static files in app.js. But I have included the middle for serving static folders.

can some one explain what is the issue

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap 
      contributors">
    <meta name="generator" content="Hugo 0.82.0">
    <title>Sign up</title>
    <link rel="canonical" 
      href="https://getbootstrap.com/docs/5.0/examples/sign-in/">
      
    <!-- Bootstrap core CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0- 
      beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384- 
      eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" 
      crossorigin="anonymous">
    <!-- Favicons -->
    <link rel="apple-touch-icon" href="/docs/5.0/assets/img/favicons/apple- 
      touch-icon.png" sizes="180x180">
    <link rel="icon" href="/docs/5.0/assets/img/favicons/favicon-32x32.png" 
      sizes="32x32" type="image/png">
    <link rel="icon" href="/docs/5.0/assets/img/favicons/favicon-16x16.png" 
      sizes="16x16" type="image/png">
    <link rel="manifest" href="/docs/5.0/assets/img/favicons/manifest.json">
    <link rel="mask-icon" href="/docs/5.0/assets/img/favicons/safari-pinned- 
      tab.svg" color="#7952b3">
    <link rel="icon" href="/docs/5.0/assets/img/favicons/favicon.ico">
    <meta name="theme-color" content="#7952b3">
    
    <style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}

@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}

    </style>
    <!-- Custom styles for this template -->
    <link href="./public/css/index.css" rel="stylesheet">
  </head>
  <body class="text-center">
  
    <main class="form-signin">
      <form action="/" , method="POST">
        <img class="mb-4" src="./public/images/image.png" alt="" width="72" 
          height="57">
        <h1 class="h3 mb-3 fw-normal">Sign Up</h1>
        
        <div class="form-floating">
          <input type="text" name="fname" class="form-control top" 
            id="firstName" placeholder="first name">
          <label for="firstName">First Name</label>
        </div>
        <div class="form-floating">
          <input type="text" name="lname" class="form-control middle" id="lastName" placeholder="last name">
          <label for="firstName">Last name</label>
        </div>
        <div class="form-floating">
          <input type="email" name="email" class="form-control bottom" id="email" placeholder="inkey@email.com">
          <label for="email">Email ID</label>
        </div>
        
        <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
        <p class="mt-5 mb-3 text-muted">&copy; 2020–2021</p>
      </form>
    </main>
    
    
    
  </body>
</html>

This is the html page taken from bootstrap The css file under the comment custom styles for this template and the png is below the form tag.

The files are added correct as when the html page is seen in the browser independently then the image and css is showing up

However when it is served using node and express the image and css arent showing up

Christian Fritz
  • 20,641
  • 3
  • 42
  • 71
Nav
  • 93
  • 9

2 Answers2

2

OK, So I am answering my own question here. After refering to @jdmayfield 's answer and searching about MIME type errors I reached link to this link.

I realised that when you set the pubic folder as static in node, Then that public folder should not be added in the path to css or images in html

Meaning that In the folder structure given above if we want to link css in html the code we use is

<link href="./public/css/index.css" rel="stylesheet">

And this gave me a MIME type error. So I changed the above code to

<link href="css/index.css" rel="stylesheet">

This worked.

However if You independently open the HTML file by going live in vscode, the css and images wont load. But when served with node they will be served.

Nav
  • 93
  • 9
  • Nicely done. I was going to update my answer then saw this! Well done. Though with a slightly different solution-- what I would recommend, basically changing "app.use(express.static(path.join(__dirname , "public")));" to " app.use(express.static(path.join(__dirname+'/public' , "public")));" This would mean your pathnames would be the same in the browser, both as ordinary local files and as http/s served files. I.E. they would both begin as "/public", referenced either way. – jdmayfield Apr 23 '21 at 06:12
  • Also, based on your post-- I'm sure you noticed, but for others who will read this, your mime-type mismatch error was coming up simply because the requested url resource did not exist. It's a good clue. Please forgive me that I missed it. But thank you for the experience. – jdmayfield Apr 23 '21 at 06:29
  • Thanks to you too, surely a good learning experience :) @jdmayfield – Nav Apr 25 '21 at 04:09
1

UPDATED POST:

In light of the recent comment by @Nav giving the error regarding mime-type, here is a snippet I found at Express: Setting content-type based on path/file?

"The Express documentation shows that it can do this if you pass in the file name."

var filePath = 'path/to/image.png';
res.contentType(path.basename(filePath));
// Content-Type is now "image/png"

Try this example first. If that does not work, reload and check Dev console for different errors. It is possible there is more than one cause of your issue.

ORIGINAL POST:

Based on the code you have submitted, I think your problem is the default CORS policy. You need to incorporate a method of allowing Cross-Origin Resource Sharing between the domains, ports, and protocols you are using. I found a good document detailing CORS explicitly, but succinctly, with a solution that appears specifically suited to your needs. You might open the Dev console in your browser and look for similar error messages as outlined in the document to confirm.

Here's the link:

https://flaviocopes.com/express-cors/

jdmayfield
  • 1,400
  • 1
  • 14
  • 26
  • 1
    Refused to apply style from 'http://localhost:3000/public/css/index.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled. ---> this error is being showed , do you know wanything about this? – Nav Apr 20 '21 at 04:24
  • What browser are you using? And have you set any custom flags regarding MIME-types? Some browsers don't associate file-extensions with a mime-type, but require the Content-type: header to be set to the mime-type explicitly. For example, Opera used to be notorious for this, though they are now running on a Chromium base like most everyone else, so this may not apply to them anymore. – jdmayfield Apr 20 '21 at 04:31
  • @Nav I updated my answer. I recall having a similar issue with a custom vanilla server I wrote a few years ago. I used an array with file-extension keys and mime-type values with a default value if none matched, and set it in the Content-type header. Since you are using Express, however, most of this work has already been included. If you still have the same issue, but the errors are different, you have successfully conquered the first cause and will need to find the second. – jdmayfield Apr 20 '21 at 04:51
  • 1
    I use chrome browser. And I dont know anything about MIME type. This is the first time i am encountering MIME type. So i havent set any custom flags , Can you say how to solve this error? – Nav Apr 20 '21 at 04:53
  • @Nav Check the update to my answer. Explanation: all files have a "mime-type" that tells the system what kind of file it is, so the the system knows how to handle it. Most people are familiar with file extensions, like whatever.txt (the .txt part is the file extension). This is roughly equivalent to the OS, however some browsers may require the Content-type header to be explicitly sent by the server. Any kind of data could be included in the file itself. It helps the browser identify what kind of data to expect and what to do with it. – jdmayfield Apr 20 '21 at 05:08