Pieter Geerkens
Pieter Geerkens

Reputation: 11893

Why is node.js not finding my HTML pages

I have a test directory C:\node_samples\hello_express set up:

enter image description here

I have a package.json file in the test directory:

{
  "name": "hello_express",
  "version": "0.0.0",
  "description": "A simple web site",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Pieter Geerkens",
  "license": "MIT",
  "private": true,
  "dependencies": {
    "express": "4.13.4",
    "formidable":  "1.x"
  }
}

I have node.js, express and formidable properly installed in a ../node_modules subdirectory (at least, success reported from the install.) by running this command from the test directory:

npm install 

I have an app.js file located in the test directory:

var express = require('express');
var app = express();
var formidable = require('formidable');

app.use('/forms', express.static(__dirname + '/public'));

app.post('/SubmitHelloPost', function (request, response) {
   if (request.method.toLowerCase() == 'post') {
      // parse form data
      var form = new formidable.IncomingForm();
      form.parse(request, function (err, fields) {
         response.writeHead(200, { 'Content-Type': 'text/html' });
         response.write('Hello ' + fields.userName + '!<br />');
         response.end('Have a POST great day!');
         console.log('Handled POST request from ' + fields.userName);
      });
   }
});

app.get('/SubmitHello', function (request, response) {
   response.writeHead(200, { 'Content-Type': 'text/html' });
   response.write('Hello ' + request.query.userName + '!<br />');
   response.end('Have a great day!');
   console.log('Handled GET request from ' + request.query.userName);
});

var port = 8081;
app.listen(port);
console.log('Listening on port: ' + port);

I open a command prompt and run node app as follows:

enter image description here

However when I attempt to run the test by navigating to either of:

http://localhost:8081/HelloForm.html
http://localhost:8081/HelloPost.html

I get an Error 404.

The html files are (HelloForm.html):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <title></title>
   <meta charset="utf-8" />
</head>
<body>
   <form method="get" action="/SubmitHello">
      Enter Name: <input type="text" name="userName" autofocus />
      <input type="submit" value="Submit" />
   </form>
</body>
</html>

and (HelloPost.html*):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <title></title>
   <meta charset="utf-8" />
</head>
<body>
   <form method="post" action="/SubmitHelloPost">
      Enter Name: <input type="text" name="userName" autofocus />
      <input type="submit" value="Submit" />
   </form>
</body>
</html>

I have no idea what is wrong. everything worked briefly after I first set it up, then stopped working.

Upvotes: 1

Views: 85

Answers (3)

Sean
Sean

Reputation: 372

It looks like there are at least 2 problems.

Problem #1

You've mounted your static asset directory at the /forms path, meaning any static assets you want to retrieve will be found at http://localhost:8081/forms/SomeFileName. You are trying to locate them directly at http://localhost:8081/HelloForm.html, which won't work. If you want to get rid of the /forms part of the path entirely, then you can remove the path argument entirely from your static asset declaration:

app.use(express.static(__dirname + '/public'));

Problem #2

You don't have these files inside the public directory anyway. They're just sitting out in your root directory. Instead you want them to be inside a folder called public, so that your static asset declaration can find them. That's why it has the word public in it, like so:

app.use('/forms', express.static(__dirname + '/public'));

So instead, create a folder in the root directory called public and move both those files (HelloForm.html and HelloPost.html) into there.

Here are the Express docs on static file serving, which show you how it works in more detail.

However, I'm guessing that even though this will work to display those 2 files, this is probably not what you ultimately want to do. My guess is that you want to use the 2 routes you've defined to show these 2 pages. My recommendation would be to read up on using a View Engine like EJS to render dynamic views, and also read up on RESTful routing to determine how to name your routes.

Upvotes: 2

Steve
Steve

Reputation: 10886

You should make a directory for those files (I'll use 'public' for this example). Then move the files you want to serve to it, and then change

app.use('/forms', express.static(__dirname + '/public'));

to

app.use('/', express.static(__dirname + '/public'));

The first argument is the server directory where clients access the files, which you want to be the root directory (i.e. '/'), and the second argument is where the files are stored. Usually you don't want to mix your public content (like html), with private content, like server logic, so you put it in a separate folder and only serve that content.

Upvotes: 3

Mattias Buelens
Mattias Buelens

Reputation: 20179

I think your problem is caused by the following line:

app.use('/forms', express.static(__dirname + '/public'));

This tells Express that when it receives requests starting with /forms, it should map those to static files in the /public folder. From your directory structure, I think this is what you're trying to do:

app.use('/', express.static(__dirname));

(It's still a good idea to move your static files to a separate directory though. Right now, navigating to http://localhost:8081/app.js would return the raw server-side code, which you probably don't want to be readable from your client-side code.)

Upvotes: 3

Related Questions