Unable to set request headers

Description

A minimal example based on this documentation:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet">
    <!-- ^^ video.js stylesheet ^^ -->
    <title>Video.JS test</title>
  </head>
  <body>
    <video autoplay controls id="player"
           poster="http://localhost:21212/img/tzGk0I0eb-4"
           class="video-js">
      <source src="http://localhost:21212/vid/tzGk0I0eb-4">
    </video>

    <script src="https://vjs.zencdn.net/7.4.1/video.js"></script>
    <!-- ^^ video.js script ^^ -->
    <script type="text/javascript">
      var headers = videojs.Hls.xhr.headers || {}
      headers['X-Arbitrary'] = 'some-arbitrary-header-text'
      videojs.Hls.xhr.headers = headers
      var player = videojs('player')
    </script>
  </body>
</html>

I also tried it with this JS (I forget where I saw this):

videojs.Hls.xhr.beforeRequest = options => {
  console.log(options)
  var headers = options.headers || {}
  headers['X-Arbitrary'] = 'some-arbitrary-header-text'
  options.headers = headers
  return options
}
var player = videojs('player')

As well as this (documented here ):

videojs.xhr({
  headers: {
    'X-Arbitrary': 'some-arbitrary-text'
  }
})
var player = videojs('player')

And this ( from here )

videojs.Hls.xhr.beforeSend = request => {
  requst.setRequestHeader('X-Arbitrary', 'some-arbitrary-text')
}
var player = videojs('player')

I have a mock server which outputs the request information:

2019-01-03 17:11:56 -05:00 :: GET -> 200:: "/img/tzGk0I0eb-4"
Host:
    - localhost:21212
User-Agent:
    - Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept:
    - */*
Accept-Language:
    - en-US,en;q=0.5
Accept-Encoding:
    - gzip, deflate
DNT:
    - 1
Connection:
    - keep-alive
Pragma:
    - no-cache
Cache-Control:
    - no-cache
2019-01-03 17:11:56 -05:00 :: GET -> 200:: "/vid/tzGk0I0eb-4"
Host:
    - localhost:21212
User-Agent:
    - Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept:
    - video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5
Accept-Language:
    - en-US,en;q=0.5
Range:
    - bytes=0-
DNT:
    - 1
Connection:
    - keep-alive
Pragma:
    - no-cache
Cache-Control:
    - no-cache
2019-01-03 17:11:56 -05:00 :: GET -> 200:: "/img/tzGk0I0eb-4"
Host:
    - localhost:21212
User-Agent:
    - Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept:
    - */*
Accept-Language:
    - en-US,en;q=0.5
Accept-Encoding:
    - gzip, deflate
DNT:
    - 1
Connection:
    - keep-alive
Pragma:
    - no-cache
Cache-Control:
    - no-cache
2019-01-03 17:11:56 -05:00 :: GET -> 200:: "/img/tzGk0I0eb-4"
Host:
    - localhost:21212
User-Agent:
    - Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept:
    - */*
Accept-Language:
    - en-US,en;q=0.5
Accept-Encoding:
    - gzip, deflate
DNT:
    - 1
Connection:
    - keep-alive
Pragma:
    - no-cache
Cache-Control:
    - no-cache

All of the examples output similar log entries, without the requested header.

Is there some updated documentation on the xhr property, or am I making some mistake in my implementation?

3 thoughts on “Unable to set request headers

  1. I tried a new technique, this got the request out to the server with the appropriate header, but when I went to actually load a video through it, I ran into further difficulty.

    <!DOCTYPE html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet">
        <!-- ^^ video.js stylesheet ^^ -->
        <title>Video.JS test</title>
      </head>
      <body>
        <video autoplay controls id="player"
               class="video-js">
          <!-- <source src=> -->
        </video>
    
        <script src="https://vjs.zencdn.net/7.4.1/video.js"></script>
        <!-- ^^ video.js script ^^ -->
        <script type="text/javascript">
          var player = videojs('player')
          videojs.xhr({
            url: "http://localhost:9999/vid/uAvMpvAyJYM",
            headers: {
              'X-Token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiZGVtb3VzZXIifQ.Et6cTa3_AQsMEj56URS6cvSO_-xDezUdId8y6RdlIa8'
            }
          }, (err, response, body) => {
            if(err) throw err;
            if( response.statusCode === 200 ) {
              player.src(body)
            } else {
              console.error(response)
            }
          })
        </script>
      </body>
    </html>

    Which downloaded the entire video, and then froze.

    I also tried it with player.src(URL.createObjectURL(body)), which threw the following exception (again after downloading the whole video)

    TypeError: Argument 1 is not valid for any of the 1-argument overloads of URL.createObjectURL.
    

    Maybe I’m getting closer here? I can’t be the first person to need to set ANY headers on a streamed video like this.

  2. I’m not really sure where you got videojs.Hls.xhr.headers, but the videojs.Hls.xhr.beforeRequest should work according to the docs. I’ve tested it locally, and it seems to be working.

    videojs.Hls.xhr.beforeRequest = function(options) {
      options.headers = {
        foo: 5
      };
      return options;
    };
    
    var player = videojs('video-player-id');
    player.src(...);
    

    It’s possible you may need to reload the source or only set it after videojs.Hls.xhr.beforeRequest is set.

  3. I have confirmed that the following HTML file does not set the appropriate headers on Firefox nor on Chromium:

    <!DOCTYPE html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet">
        <!-- ^^ video.js stylesheet ^^ -->
        <title>Video.JS test</title>
      </head>
      <body>
        <video autoplay controls id="player"
               poster="http://localhost:21242/img/tzGk0I0eb-4"
               class="video-js">
        </video>
    
        <script src="https://vjs.zencdn.net/7.4.1/video.js"></script>
        <!-- ^^ video.js script ^^ -->
        <script type="text/javascript">
          videojs.Hls.xhr.beforeRequest = function(options) {
            options.headers = { test: 'header' }
            return options
          }
          var player = videojs('player')
          player.src("http://localhost:21242/vid/tzGk0I0eb-4");
        </script>
      </body>
    </html>