1

I'm trying to use the Express router to send static .html files based on the URL provided in router.get.

For example, this sends the homepage

router.get('/', function(req, res, next) {
res.sendFile('index.html');
});

And this sends the "about" page

router.get('/about', function(req, res, next) {
res.sendFile("about.html")
});

When the app first loads, it loads the index.html as expected. But for some reason, when I visit localhost:3000/about I get a 404 error. The about.html is definitely there though because I can go to localhost:3000/about.html and the page loads.

Here are some of my other Express files if that helps.

App.js (I used the express generator for this. Only added reference to express.static to reference the public folder)

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var users = require('./routes/users');
// var config = require('./config')['dev']

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

//Validate inputs
const { body,validationResult } = require('express-validator/check');
const { sanitizeBody } = require('express-validator/filter');

// view engine setup
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'jade');

app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

//Setup public for static files
app.use(express.static(path.join(__dirname, 'public')));

//Use index file for router
app.use('/', index);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.send('You\'ve reached the end of the Internet :)')
});

module.exports = app;

index.js (includes express router)

var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var db= require('db')

// Routes
/* GET home page. */
router.get('/', function(req, res, next) {
  res.sendFile('index.html');
});

router.get('/about', function(req, res, next) {
  res.sendFile("about.html")
});

module.exports = router;

Any help provided is much appreciated!

DLee
  • 7,856
  • 4
  • 19
  • 23

1 Answers1

0

Based on your description, it seems like your express.static() is loading index.html for you and is also making http://localhost:3000/about.html work for you. But, neither of your manually created routes actually would work because res.sendFile("about.html") doesn't reference a file in the right directory.

So, you would need to fix the path to that file:

router.get('/about', function(req, res, next) {
  res.sendFile(path.join(__dirname, "../public", "about.html"), {dotfiles: "allow"});
});

This assumes these files are in your public directory and that it's a sub-directory below __dirname (which it appears from your express.static() line of code), but if that's not the case, then just adjust the path in the above line of code to manually point at the public directory.

FYI, the reason that index.html works is because express.static() has special logic to look for index.html when the path is just /. But, /about won't automatically look for about.html.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • So I change it to res.sendFile(path.join(__dirname, "../public", "about.html")) since __dirname points to the routes folder which is on the same level as public. With that change, I now get a 500 error now.... – DLee Apr 05 '18 at 17:53
  • Just to check if it was about.html causing the error, I changed it to index.html instead in the res.sendFile. Still getting 500 error. – DLee Apr 05 '18 at 17:53
  • @DLee - I'm not sure why you used a different path than I recommended? Did you try what I recommended which is based on the fact that your `express.static()` code is working for `index.html`. Where exactly is your `public` directory relative to `__dirname`. – jfriend00 Apr 05 '18 at 17:58
  • Oh wait. I got it. Apparently ../ is considered malicious code so it throws 500. Solution to that is [here](https://stackoverflow.com/questions/14594121/express-res-sendfile-throwing-forbidden-error) – DLee Apr 05 '18 at 17:58
  • Public is on the same level as __dirname which is why I had to .. to go up a directory. I ended up using res.sendFile('about.html', {root: './public'}) to get it to work. – DLee Apr 05 '18 at 18:04
  • @DLee - You have me pretty confused then because if `public` is at the same level as `__dirname`, I have no idea how `app.use(express.static(path.join(__dirname, 'public')));` could ever work. That's going to look in a sub-directory `public` below `__dirname`. – jfriend00 Apr 05 '18 at 18:07
  • So `app.use(express.static(path.join(__dirname, 'public')));` is in my App.js so __dirname is root/ at that point. Because index.js is in the routes subdirectory when I call `res.sendFile(path.join(__dirname, "public", "about.html")); ` __dirname is root/routes at that point – DLee Apr 05 '18 at 20:07
  • @DLee - OK, that explains it. We get so many questions here about this type of thing and people don't explain their directory hierarchy which makes it hard to advise properly. Anyway, glad you got it figured out. – jfriend00 Apr 05 '18 at 20:20
  • Sorry for all the confusion! Thanks for all the help :) – DLee Apr 05 '18 at 20:22