What you expected to happen
Playing stream.
What actually happened
Stream not playing.
Uncaught (in promise) DOMException: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
Hi. I have a problem with xhrSetup function in hls.js API.
I have async function to get access token and then i want paste access token to request header called Authorization. Now when i'm try to do this i get an error:
Uncaught (in promise) DOMException: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
This is code example:
xhrSetup: async (xhr, url) => {
const accessToken = await getAccessToken()
xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`)
}
I think problem in this file, because function is not async: https://github.com/video-dev/hls.js/blob/master/src/utils/xhr-loader.js
xhr.setRequestHeader expects xhr.readyState === OPEN
you can try manually opening xhr before setting headers
xhrSetup: async (xhr, url) => {
const accessToken = await getAccessToken()
xhr.open('GET', url, true);
xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`)
}
It's not working too, because request is already done (200 code) when i'm try to set request header with my accessToken.
When i add this xhr.open('GET', url, true); my request to manifest is canceled.
xhrSetup() is not expected to be async
you might need to completely rewrite / override existing xhrLoader
I created a pull request (https://github.com/video-dev/hls.js/pull/1361) to show you what i want to change. It's working for my case and standard usage of xhrSetup not broken. Since i'm using async/await, i need to add babel-preset-stage-0 and babel-pollyfill, but i don't know it's good or not.
Can you offer a better solution ?
I think your use case is too specific.
It always possible to design a solution and handle asynchronous behavior outside of the library.
I see how the change is more convenient for you but I don't see how such change is more generic for a majority of the library users.
I think it's unnecessary to introduce async/await polyfill to the project to solve a narrow use-case.
Ok, i understand you. XHR is old way to get via http. I found this in your repository - https://github.com/video-dev/hls.js/blob/master/src/utils/fetch-loader.js
I don't understand why you don't use it, i think it's suitable for me, because in this case uses promises.
Maybe we think about to rewrite xhr-loader to fetch way ?
@PidginEnemy I think we use XHR because you can't abort fetch.
yes, we can't abort Fetch
@PidginEnemy i would suggest you to use the following as I agree with @NicolasSiver that it is unnecessary to change xhrSetup() API for a narrow use-case
class myLoader extends Hls.DefaultConfig.loader {
loadInternal() {
// existing loadInternal, either using xhrSetup() with async/await or hardcoding your own biz logic
}
}
@mangui thanks for your solution, i'l try this.
closing as no plan to change xhr-loader API in the short term
Most helpful comment
I think your use case is too specific.
It always possible to design a solution and handle asynchronous behavior outside of the library.
I see how the change is more convenient for you but I don't see how such change is more generic for a majority of the library users.
I think it's unnecessary to introduce
async/awaitpolyfill to the project to solve a narrow use-case.