Service-Worker fetch on videos (big files?) not working for certain file sizes
Reported by
michael....@googlemail.com,
Oct 22 2016
|
||||
Issue description
Chrome Version : 53.0.2785.143
Other browsers tested:
Safari:
Firefox: OK 48.0.2
IE:
What steps will reproduce the problem?
(1) without service worker active, both videos are displayed
(2) activate the service worker (having a fetch event listener which simply fetches all), restart Chrome (I don't know why the fetch listener does not get activated for the current session)
(3) The right video (5s) is displayed, the left not (3s). Each time the button "Fill video src attribute" is pressed, the fetch(...).then(...) is executed (it prints the debug output for the non-displayed video to console) but the video is not displayed
What is the expected result?
The videos should display independent of service worker active or not.
What happens instead?
White background without the video
Attached a screenshot.
,
Oct 25 2016
I can't reproduce this issue. Can you provide me the log of chrome://net-internals?
,
Oct 25 2016
,
Oct 25 2016
,
Oct 25 2016
Could you please record chrome://tracing with "ServiceWorker" and "net" and "netlog" in Record Categories and "net" in Disabled by Default Categories?
,
Oct 25 2016
Ah, it's the first time I see that ... I did not find "netlog" as a checkbox, let me know if you need another trace. BTW sometimes both videos are not displayed (approx 30%), very seldom both videos are displayed (approx 2%, I had GMail open in another tab, but I could not reproduce it).
,
Oct 25 2016
According to the log, I think 4 fetch events are executed.
2 events for video_05s.mp4 and 2 events for video_03s.mp4.
Could you please check the request header?
If you check "Preserve log" flag in the DevTools console tab, you will see 4 logs.
self.addEventListener('fetch', function(event) {
console.log(event.request.url);
event.request.headers.forEach((v, n) => { console.log(' ' + n + ': ' + v); });
event.respondWith(
fetch(event.request)
.then(function(response) {
console.log(response.url);
return response;
})
);
});
,
Oct 26 2016
Ok, there was no mime-type (I use embedded tomcat without web.xml). I added mime type, but same problem. Attached is a screenshot from devtools, can see the mime type, the 4 logs but also 2x canceled?
,
Oct 26 2016
I want to know the headers of FetchEvent.request.
event.request.headers.forEach((v, n) => { console.log(' ' + n + ': ' + v); });
,
Oct 26 2016
http://127.0.0.1/gui/test/video_03s.mp4 sw.js:7 accept: */* sw.js:7 accept-encoding: identity;q=1, *;q=0 sw.js:7 user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36 sw.js:7 range: bytes=0- sw.js:6 http://127.0.0.1/gui/test/video_05s.mp4 sw.js:7 accept: */* sw.js:7 accept-encoding: identity;q=1, *;q=0 sw.js:7 user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36 sw.js:7 range: bytes=0- sw.js:11 http://127.0.0.1/gui/test/video_03s.mp4 sw.js:11 http://127.0.0.1/gui/test/video_05s.mp4 sw.js:6 http://127.0.0.1/gui/test/video_03s.mp4 sw.js:7 accept: */* sw.js:7 accept-encoding: identity;q=1, *;q=0 sw.js:7 user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36 sw.js:7 range: bytes=688128- sw.js:11 http://127.0.0.1/gui/test/video_03s.mp4 Attached is modified sw.js
,
Oct 26 2016
For the console output in comment 10: video_03s.mp4 is not displayed, video_05s.mp4 is displayed.
,
Oct 27 2016
I understood what is happening.
1. The mode of fetch requests from <video> element is "no-cors".
2. The request from <video> element has a range header ("Range: bytes=").
3. But when the service worker sends the request to the server with "fetch(event.request)", this range header is removed.
This behavior is written in the Fetch spec. https://fetch.spec.whatwg.org/#concept-headers-append
> 5. Otherwise, if guard is "request-no-cors" and name/value is not a CORS-safelisted request-header, return.
4. If the range header is "bytes=0-", there is no problem.
But when the range is not "bytes=0-", the server returns the video file from the first byte, and the video element can't handle the response correctly.
I don't know well when video elements send non-0-start range requests.
But even if the user doesn't seek, the video elements sometimes send non-0-start range requests.
I think you can avoid this problem like this:
self.addEventListener('fetch', function(event) {
var request = event.request;
if (event.request.url.indexOf('.mp4') != -1) {
request = new Request(request, {mode: "same-origin"});
}
event.respondWith(
fetch(request)
.then(function(response) {
console.log(response.url);
return response;
})
);
});
,
Oct 27 2016
,
Oct 27 2016
That solved it, thank you! |
||||
►
Sign in to add a comment |
||||
Comment 1 by jri@chromium.org
, Oct 24 2016