2015-04-16 15 views
13

Mam pracownika serwisu, który przechwytuje żądania mojej strony (zdarzenie fetch), a gdy adres URL pasuje do określonego wzorca, pobierze inny adres URL i zastąpi odpowiedź nową treścią. Działa idealnie dla danych tekstowych (JS, XML ...) lub danych binarnych (np. Obrazów), ale jeśli chodzi o wideo, to jest usterka.Jak mogę przesłać strumieniowo wideo z ServiceWorker?

Używam Chrome 41 na OSX.

To jest uproszczony kod mojego pracownika:

self.addEventListener('fetch', function(event) { 
    var url = event.request.url; 
    console.log('SW: fetch', url); 
    if (/\.mp4$/.test(url)) { 
    url = 'https://vjs.zencdn.net/v/oceans.mp4'; 
    var options = { 
     credentials: 'include', 
     mode: 'no-cors' 
    }; 
    event.respondWith(fetch(url, options)); 
    } 
}); 

I to jest uproszczony kod na mojej stronie HTML:

navigator.serviceWorker.register('sw.js').then(function(reg) { 
    console.info('ServiceWorker registration successful for', reg.scope); 

    var video = document.createElement('video'); 
    video.src = '/video.mp4'; 
    video.controls = true; 
    video.autoplay = true; 
    video.onerror = function(err) { 
    console.error('Video load fail', err); 
    } 
    video.onload = function(data) { 
    console.info('Video load success'); 
    } 
    document.body.appendChild(video); 

}).catch(function(err) { 
    console.error('ServiceWorker registration failed:', err); 
}); 

Gdy po raz pierwszy załadować stronę, pracownik instaluje, więc żądanie wideo nie zostanie przechwycone, a więc nie powiedzie się. Ale po ponownym załadowaniu strony (bez czyszczenia pamięci podręcznej), zostaje ona pomyślnie przechwycona, a robotnik pomyślnie ładuje wideo (HTTP 200 w swoim inspektorze), ale z jakiegoś powodu strona główna wyrzuca net::ERR_FAILED.

I nie mogę ręcznie odczytu/strumieniowo go, ponieważ pochodzi z innego pochodzenia, w wyniku „nieprzezroczyste” typ reakcji: http://www.w3.org/TR/service-workers/#cross-origin-resources

UPDATE: aktualizacji do Chrome 42, błąd jest teraz HTTP 400 Service Worker Fallback Required (from ServiceWorker). Dziwne jest to, że the source code (linia 510) wskazuje, że powinno być podniesione tylko wtedy, gdy brakuje nagłówków CORS, ale tutaj trybem jest no-cors.

Odpowiedz

7

Po pierwsze, polecam próbować w bieżącym Chrome Canary, który obecnie odpowiada wersji 44.0.2371.0. Deweloper przy robotach serwisowych stale się poprawia wraz z każdym nowym wydaniem Chrome, a jego wersja jest znacznie lepsza w wersji 43+.

Nie wygląda na to, że obiekty opaque Response mogą być używane dla elementu src elementu <video> i zakładam, że jest to celowe. (Nieprzezroczyste Response s mogą być używane do pewnych celów, i obawiam się, że nie mam pełnego podsumowania tego, co będzie i nie będzie działać z nieprzezroczystym Response.)

Ale w każdym razie jesteś szczęście w tym vjs.zencdn.net obsługuje CORS, więc możesz uciec z użyciem domyślnego, obsługującego CORS Request, który da ci nieprzezroczyste Response.

Jedna rzecz, że nie można zrobić jest użycie credentials: 'include' w swoim CORS Request, ponieważ doprowadzi to do API Fetch nie może załadować https://vjs.zencdn.net/v/oceans.mp4. Symbol wieloznaczny "*" nie może być użyty w nagłówku "Access-Control-Allow-Origin", gdy flaga poświadczeń jest prawdziwa. Błąd. Nie wydaje się, że jest to problem z konkretnym hostem, ponieważ poświadczenia nie są wymagane.

Po zmianie kodu na event.respondWith(fetch('https://vjs.zencdn.net/v/oceans.mp4')); wszystko działało bez zarzutu.

+0

Wielkie dzięki Jeff, nagłówki CORS były rzeczywiście problemem! – antoine129

+0

Mam problem z śledzeniem Chromium, aby ulepszyć debugowanie: https://code.google.com/p/chromium/issues/detail?id=477685 – antoine129

Powiązane problemy