简体   繁体   中英

Code doesn't serve my static html files in the publlic folder

Exploring express framework. Learning the express.static middleware but it doesn't function the way I expect it to.

Code:

const express = require("express");
const app = express();

app.use((req, res, next) =>{
    express.static('public');
    next();
}); 

app.use((req, res) => {
  console.log("Starting first middleware");
});

app.listen(3000);

The above code doesn't serve my static html files in the publlic folder. The public folder is on the same directory as this JS file, and when I for instance use the URL http://localhost:3000/home.html to try to access the home.html file in the public folder I cannot access it.

When I switch up the order that the express.static is last it does serve my static html file in the public folder.

Code:

app.use((req, res, next) => {
  console.log("Starting first middleware");
  next();
});

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

Question:

Why doesn't my app in the first code example serve the static files?

express.static is a function that returns another function (middleware), and Express middlewares expect 2 or 3 parameters (req, res[, next]).

When it is used as a callback, like this:

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

you don't need to explicitly provide parameters to it, since app.use will provide them for you.

However, when you use it yourself, you need to explicitly call the function with its parameters:

app.use((req, res, next) =>{
    express.static('public')(req, res, next);
    next();
});

In your first example, you were generating the middleware, but not executing it.

There is a fundemental difference between the two snippets. You see the first one you are basically calling the function express.static with argument 'public' inside the callback function of a middleware you declared, this only will return a function that will not be used in next middlewares as no arguments passed to it; the req object should be passed to it. However in the second one this will return a function that can use the req object which is passed along with the res normally in the app.use. Take a look at some of the source code of the 'static' function to get an idea :

 function serveStatic (root, options) {
  if (!root) {
    throw new TypeError('root path required')
  }

  if (typeof root !== 'string') {
    throw new TypeError('root path must be a string')
  }

  // copy options object
  var opts = Object.create(options || null)

  // fall-though
  var fallthrough = opts.fallthrough !== false

  // default redirect
  var redirect = opts.redirect !== false

  // headers listener
  var setHeaders = opts.setHeaders

  if (setHeaders && typeof setHeaders !== 'function') {
    throw new TypeError('option setHeaders must be function')
  }

  // setup options for send
  opts.maxage = opts.maxage || opts.maxAge || 0
  opts.root = resolve(root)

  // construct directory listener
  var onDirectory = redirect
    ? createRedirectDirectoryListener()
    : createNotFoundDirectoryListener()

  return function serveStatic (req, res, next) { // the funciton returned
    if (req.method !== 'GET' && req.method !== 'HEAD') {
      if (fallthrough) {
        return next()
      }

      // method not allowed
      res.statusCode = 405
      res.setHeader('Allow', 'GET, HEAD')
      res.setHeader('Content-Length', '0')
      res.end()
      return
    }

    var forwardError = !fallthrough
    var originalUrl = parseUrl.original(req)
    var path = parseUrl(req).pathname

    // make sure redirect occurs at mount
    if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {
      path = ''
    }

    // create send stream
    var stream = send(req, path, opts)
    //rest of code...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM