Search code examples
node.jsexpresshtml5-videopug

Express route fires a second time


I have a program which I have reduced to almost nothing, and still get the problem that, if I include a HTML5 Video construct, then the initial route gets called twice.

app.js

var express = require('express');
var path = require('path');

var app = express();
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));

app.set('port', process.env.PORT || 4107);

app.get('/v/:vkey', function(req, res) {
  console.log('-------------- V -------');
  console.log(req.url);
  console.log(req.params);
  res.send('<!DOCTYPE html><html lang="en"><head><link href="/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"><script src="/vendor/bootstrap/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script></head><body><div id="vidguts"><div class="container-fluid"><div class="card mt-2"><div class="card-header"><h5>Video</h5></div><div class="card-body"><div class="row"><div class="col"><video controls="" width="100%" height="100%" autoplay=""><source src="beach0.mp4" type="video/mp4"></video></div></div></div></div></div></div></body></html>');
});
  
var server = app.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

The html sent is (in PUG format to make it easy to read)

doctype html
html(lang="en")
  head
    link(href="/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet")
    script(src="/vendor/bootstrap/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous")

  body
    #vidguts
      .container-fluid
        .card.mt-2
          .card-header
            h5 Video
          .card-body
            .row
              .col
                video(controls width="100%" height="100%" autoplay="")
                  source(src="beach0.mp4" type="video/mp4")

Output:

Express server listening on port 4107
-------------- V -------
/v/13
{ vkey: '13' }
-------------- V -------
/v/beach0.mp4
{ vkey: 'beach0.mp4' }

So Express is somehow calling the 'v' route a 2nd time, with the vkey param being the 'src' attribute on the HTML5 Video construct. No video appears on the page, just a blank video screen (with the video controls, etc... but no actual video).

Node: v16.20.2 Express: v4.19.2

I call this test program using: localhost:4107/v/13


Solution

  • It's just a common error with express when using params, it can be resolved by referencing the root path so it could fetch the video from public directory.

    doctype html
    html(lang="en")
      head
        link(href="/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet")
        script(src="/vendor/bootstrap/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous")
    
      body
        #vidguts
          .container-fluid
            .card.mt-2
              .card-header
                h5 Video
              .card-body
                .row
                  .col
                    video(controls width="100%" height="100%" autoplay="")
                      source(src="/beach0.mp4" type="video/mp4")
    

    In app.js

    app.get('/v/:vkey', function(req, res) {
      console.log('-------------- V -------');
      console.log(req.url);
      console.log(req.params);
      res.send('<!DOCTYPE html><html lang="en"><head><link href="/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"><script src="/vendor/bootstrap/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script></head><body><div id="vidguts"><div class="container-fluid"><div class="card mt-2"><div class="card-header"><h5>Video</h5></div><div class="card-body"><div class="row"><div class="col"><video controls="" width="100%" height="100%" autoplay=""><source src="/beach0.mp4" type="video/mp4"></video></div></div></div></div></div></div></body></html>');
    });