MarcoLe
MarcoLe

Reputation: 2509

Express - Edit HTML before serving as static server

Before I call expressApp.use(express.static(path.join(__dirname, '/../frontend/dist'))); I need to modify the html-code. What I basically need to do is inserting meta tags in two middleware functions. I figured out how to do this. But with my solution I call a middleware-functions inside another one.

app.js

let frontend = await fs
  .readFileSync(path.join(__dirname, '/../frontend/dist/index.html'))
  .toString('utf8');

expressApp.use((req, res, next) => {
  //...
  frontend = frontend.replace(
    '<meta device="ABC" />',
    '<head><meta device="' + deviceId + '"/>'
  );
  next();
});

expressApp.use((req, res, next) => {
  const language = req.get('language') || 'en_GB';
  logger.info('language:' + language);
  this._languageModule.setLanguage(language);
  frontend = this._languageModule.insertSIDs(frontend);
  logger.info(frontend);
  expressApp.use(express.static(path.join(__dirname, '/../frontend/dist'))); // nested middleware function
  next();
});

/** set up all the express routes **/
expressApp.get('/', (req, res) => {
  res.send(frontend);
});

Edit

If I don't call expressApp.use(express.static(path.join(__dirname, '/../frontend/dist'))); nested - like this:

expressApp.use((req, res, next) => {
  const language = req.get('language') || 'en_GB';
  logger.info('language:' + language);
  this._languageModule.setLanguage(language);
  frontend = this._languageModule.insertSIDs(frontend);
  logger.info(frontend);
  next();
});

expressApp.use(express.static(path.join(__dirname, '/../frontend/dist')));

the HTML will not be served modified.

Upvotes: 0

Views: 2855

Answers (1)

Playdome.io
Playdome.io

Reputation: 3225

You probably should write your own middleware that handles the modification of the files. Here's an example not tested. But it's rough. It's based on the express.static function

const fs = require("fs");
var parseUrl = require('parseurl')

app.use((req, res, next) => {

    var originalUrl = parseUrl.original(req)
    var path = parseUrl(req).pathname

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

    // We only answer to GET 
    if (req.method !== 'GET' && req.method !== 'HEAD') {
        return next()
    }

    let path = path;
    fs.exists(path, (exists) => {
        if(!exists)
        {
            // file don't exists skip this middleware
            return next();
        }
        fs.readFile(path, (err, data) => {
            if (err)
            {
                // Can't send the file skip this middle ware
                return next();
            }


            // Do whatever you need with the file here?
            // ...


            // Setup mime type of the file
            res.setHeader("content-type", "text/html");
            // send the client the modified html
            res.send(data);
        });
        console.log(exists ? 'it\'s there' : 'no passwd!');
    });
});

For the original source please take a look at this github page: https://github.com/expressjs/serve-static/blob/master/index.js

Upvotes: 1

Related Questions