-
Notifications
You must be signed in to change notification settings - Fork 425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: onRequest hooks called too late #1396
Changes from 4 commits
3340014
cdfa622
66865b8
1646e2d
84618bd
8a30a0c
ac4ff45
c25a03a
e562b51
2772876
f1dadd8
4e3130f
538aac2
7f062e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,7 @@ Video.js Compatibility: 7.x, 8.x | |
- [vhs.stats](#vhsstats) | ||
- [Events](#events) | ||
- [loadedmetadata](#loadedmetadata) | ||
- [xhr-hooks-ready](#xhr-hooks-ready) | ||
- [VHS Usage Events](#vhs-usage-events) | ||
- [Presence Stats](#presence-stats) | ||
- [Use Stats](#use-stats) | ||
|
@@ -644,20 +645,34 @@ callback function as a parameter as well as `offRequest` and `offResponse` | |
functions which will remove a callback function from the `onRequest` or | ||
`onResponse` set if it exists. | ||
|
||
The `onRequest(callback)` function takes a `callback` function that will pass the xhr `request` | ||
Object to that callback. These callbacks are called synchronously, in the order registered | ||
and act as pre-request hooks for modifying the xhr `request` Object prior to making a request. | ||
The `onRequest(callback)` function takes a `callback` function that will pass the xhr `options` | ||
Object to that callback. These callbacks are called synchronously, in the order registered | ||
and act as pre-request hooks for modifying the xhr `options` Object prior to making a request. | ||
|
||
Example: | ||
```javascript | ||
const playerRequestHook = (request) => { | ||
const requestUrl = new URL(request.uri); | ||
const playerRequestHook = (options) => { | ||
const requestUrl = new URL(options.uri); | ||
requestUrl.searchParams.set('foo', 'bar'); | ||
request.uri = requestUrl.href; | ||
options.uri = requestUrl.href; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will need to update these samples to return the It would make sense to document the behavior here - each Also, we should document that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I wasn't 100% sure that we wanted to document it that way as it wasn't clear whether we would remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added |
||
}; | ||
player.tech().vhs.xhr.onRequest(playerRequestHook); | ||
``` | ||
|
||
If access to the `xhr` Object is required prior to the `xhr.send` call, an `options.beforeSend` | ||
callback can be set within an `onRequest` callback function that will pass the `xhr` Object | ||
as a parameter and will be called immediately prior to `xhr.send`. | ||
|
||
Example: | ||
```javascript | ||
const playerXhrRequestHook = (options) => { | ||
options.beforeSend = (xhr) => { | ||
xhr.open('GET', 'https://new.uri'); | ||
}; | ||
}; | ||
player.tech().vhs.xhr.onRequest(playerXhrRequestHook); | ||
``` | ||
|
||
The `onResponse(callback)` function takes a `callback` function that will pass the xhr | ||
`request`, `error`, and `response` Objects to that callback. These callbacks are called | ||
in the order registered and act as post-request hooks for gathering data from the | ||
|
@@ -704,22 +719,32 @@ player.tech().vhs.xhr.beforeRequest = function(options) { | |
|
||
The global `videojs.Vhs` also exposes an `xhr` property. Adding | ||
`onRequest`, `onResponse` hooks and/or specifying a `beforeRequest` | ||
function that will allow you to intercept the request Object, response | ||
data and options for *all* requests in every player on a page. For | ||
consistency across browsers the video source should be set at runtime | ||
function that will allow you to intercept the request options, xhr | ||
Object, error and response data for *all* requests in every player on a page. | ||
For consistency across browsers the video source should be set at runtime | ||
once the video player is ready. | ||
|
||
Example: | ||
```javascript | ||
// Global request callback, will affect every player. | ||
const globalRequestHook = (request) => { | ||
const requestUrl = new URL(request.uri); | ||
const globalRequestHook = (options) => { | ||
const requestUrl = new URL(options.uri); | ||
requestUrl.searchParams.set('foo', 'bar'); | ||
request.uri = requestUrl.href; | ||
options.uri = requestUrl.href; | ||
}; | ||
videojs.Vhs.xhr.onRequest(globalRequestHook); | ||
``` | ||
|
||
```javascript | ||
// Global request callback defining beforeSend function, will affect every player. | ||
const globalXhrRequestHook = (options) => { | ||
options.beforeSend = (xhr) => { | ||
xhr.open('GET', 'https://new.uri'); | ||
adrums86 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
}; | ||
videojs.Vhs.xhr.onRequest(globalXhrRequestHook); | ||
``` | ||
|
||
```javascript | ||
// Global response hook callback, will affect every player. | ||
const globalResponseHook = (request, error, response) => { | ||
|
@@ -796,6 +821,11 @@ are triggered on the player object. | |
Fired after the first segment is downloaded for a playlist. This will not happen | ||
until playback if video.js's `metadata` setting is `none` | ||
|
||
#### xhr-hooks-ready | ||
|
||
Fired when the player `xhr` object is ready to set `onRequest` and `offRequest` hooks, as well | ||
as remove hooks with `offRequest` and `offResponse`. | ||
|
||
### VHS Usage Events | ||
|
||
Usage tracking events are fired when we detect a certain HLS feature, encoding setting, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,6 +99,8 @@ const xhrFactory = function() { | |
// TODO: switch back to videojs.Vhs.xhr.name === 'XhrFunction' when we drop IE11 | ||
const xhrMethod = videojs.Vhs.xhr.original === true ? videojsXHR : videojs.Vhs.xhr; | ||
|
||
// call all registered onRequest hooks | ||
callAllHooks(_requestCallbackSet, options); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like I don't think this is a bad implementation, but it could be a breaking change to videojs.Vhs.xhr.beforeRequest = (options) => {
// Ignores `options` and returns a totally new object.
return {...};
}; We probably don't want that to break, so perhaps the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great catch @misteroneill ! I added some logic to support both cases and a test for the use case you described. Let me know what you think. |
||
const request = xhrMethod(options, function(error, response) { | ||
// call all registered onResponse hooks | ||
callAllHooks(_responseCallbackSet, request, error, response); | ||
|
@@ -112,9 +114,6 @@ const xhrFactory = function() { | |
}; | ||
request.uri = options.uri; | ||
request.requestTime = Date.now(); | ||
// call all registered onRequest hooks | ||
callAllHooks(_requestCallbackSet, request); | ||
|
||
return request; | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thought on these samples, should they be wrapped in an
xhr-hooks-ready
event callback to show the recommended approach?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, will add examples with the event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the
'xhr-hooks-ready'
event listener to all the per-player examples.