0

To Admins, I have spent the whole day searching, trying and retrying many different answers dealing with Node Js, Express and Static files I found all over stackoverflow and on the internet and I still have not found a single piece of code or hints or clues that help me one bit. So, if this question that I am asking is very similar or duplicate to others, I apologize. I am frustrated.

Having said that I searched online for a very very simple EXAMPLE of what I am trying to do. Then, I followed the tutorial to the TEETH and still it won't work as expected. All I want to be able to do is have NodeJs server serve static files like images and javascript. Here is the code.

NodeJS or Server.js

const express = require('express');
const app = express();
const PORT = 3000;

app.use(express.static('public'));

app.get('/', (req, res) => {
    res.send('Hello World!'); <--- This does not load index.html.
});

//app.get("/",function(req,res){
//    res.sendFile(__dirname + '/index.html'); <---this what I added to load index.html
//});

app.listen(PORT, () => console.log(`Server listening on port: ${PORT}`));

index.html

  <html>
  <head>
  <title>Hello World!</title>
  </head>
  <body>
  <h1>Hello, World!</h1>
  <img src="shark.png" alt="shark">
  </body>
  </html>

The interesting thing about this simple code is that on the client side (Browser) there is not a single error in the console.

So, what is wrong with this code? Why is this code refuseing to serve simple image file?

ThN
  • 3,235
  • 3
  • 57
  • 115
  • Does this answer your question? [static files with express.js](https://stackoverflow.com/questions/10434001/static-files-with-express-js) – ggorlen May 04 '21 at 19:16
  • 1
    To sort this out, we need to see your file hierarchy on your server's hard disk and we need to now where `index.html`, `shark.png` and `server.js` are in that file hierarchy and exactly how you are starting your server. Then, we need to know exactly what URL you are using to access your index.html in the browser. – jfriend00 May 04 '21 at 19:18
  • @ggorlen yes it is – ThN May 04 '21 at 19:19
  • So, if `res.sendFile(__dirname + '/index.html');` properly sends your `index.html` file, then it is apparently NOT in your `public` directory (it appears to be in the same directory as `server.js` so that's why `express.static()` does not find it because you told `express.static()` to look only in your `public` directory. – jfriend00 May 04 '21 at 19:20
  • @jfriend00 public folder -- > server.js, index.html, shark.png. They are all in the same folder which is folder called public. – ThN May 04 '21 at 19:22
  • @jfriend00 So, what you are telling me is server.js can't be located within the same folder as the static files? – ThN May 04 '21 at 19:24
  • 1
    Well, server.js should NEVER be in the public folder - you're providing public access to your server source code. And, `app.use(express.static('public'));` is looking for a sub-directory named `public` and it isn't finding it. `public` should be a separate directory that contains only files meant to be sent to a browser or publicly accessed. And, `express.static('public')` needs to point to that directory properly. Right now, it's looking in `__dirname + /public' and there is apparently no such directory because `__dirname` is already the `public` directory. – jfriend00 May 04 '21 at 19:25
  • @jfriend00 That makes a lot of sense. okay... well, it is quitting time... I will have to try this tomorrow... Thanks. – ThN May 04 '21 at 19:28

1 Answers1

1

If server.js is already in the public directory, then express.static('public') will be looking for a sub-directory named public which will essentially be looking for:

__dirname + '/public`

and it won't find that directory so won't match anything there. That's why your express.static() isn't working.

In general, your server source code should NOT be in the public directory because you're exposing your server source to the public when you set it up that way.

I would suggest this layout:

  project name
     server
         server.js
     public
         index.html
         shark.png

Then, you can use

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

I like this layout because the public files are in a completely separate tree from the private server files, yet both are located within the project.


Also note that resources like images should be referenced with absolute URLs, not relative URLs so change this:

<img src="shark.png" alt="shark">

to

<img src="/shark.png" alt="shark">

Both will work in this trivial example, but as soon as you start to have a path on your HTML files such as /categories/trees.html, then the <img> tag that has a src of "shark.png" will end up causing a request to /categories/shark.png and will no longer work. Whereas if the src is "/shark.png" it will continue to work and will be independent of the path of the HTML page (which is what you want).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Wow... I thought I knew everything about Node JS programming after going through bunch of tutorials start to finish. I am so happy to see the image of that shark on the browser... :) Your answer works. – ThN May 05 '21 at 13:54