当从 Firebase 提供时,带有范围请求路由器的 Workbox pre-cached 音频无法在 Chrome 中播放
Workbox pre-cached audio with range requests router fails to play in Chrome when served from Firebase
背景
我创建了一个 PWA 测试项目来了解如何让音频缓存与 Workbox 一起工作,
包括 scrub/seek 使用 range requests plugin.
我希望该应用预缓存所有音频,并使该音频可以离线播放,包括 scrub/seek。
Pre-caching 音频可以通过以下两种方式之一完成:
- 使用 Workbox injectManifest.
- 通过使用
cache.add(URL)
手动将音频文件添加到缓存
但是使用第一种方法 (injectManifest) 缓存的音频文件不会 scrub/seek 因为 Workbox pre-cache 不会
支持范围请求 headers。所以你需要在前面放一个启用范围请求的路由器
pre-cache 对于音频文件,如果您希望能够在缓存的音频文件中擦除 through/seek。
问题
Pre-cached 启用范围请求的音频将播放,并且 scrub/seek 在 Chrome 和 Firefox 中正常播放应用程序
来自 localhost 但在 Chrome 从 Firebase 提供时无法播放。
我看到所有 pre-cached 前面有范围请求路由器的音频文件都出现同样的错误:
Router is responding to: /media/audio/auto-pre-cached.mp3
Using CacheOnly to respond to '/media/audio/auto-pre-cached.mp3'
No response found in the 'act-auto-pre-cache-wbv4.3.1-actv0.0.1' cache.
The FetchEvent for "https://daffinm-test.firebaseapp.com/media/audio/auto-pre-cached.mp3" resulted in a network error response: the promise was rejected.
CacheOnly.mjs:115 Uncaught (in promise) no-response: The strategy could not generate a response for 'https://daffinm-test.firebaseapp.com/media/audio/auto-pre-cached.mp3'.
at CacheOnly.makeRequest (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-strategies.dev.js:343:15)
Chrome 尝试过的版本:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
这些文件存在于 Workbox 缓存中。我在 locahost 和 Firebase 之间看到的唯一区别是缓存响应 headers:
本地主机
cache-control: max-age=3600
content-length: 3770956
content-type: audio/mpeg; charset=utf-8
Date: Mon, 07 Oct 2019 09:37:03 GMT
etag: "12456134-3770956-"2019-09-29T20:05:00.314Z""
last-modified: Sun, 29 Sep 2019 20:05:00 GMT
server: ecstatic-2.2.2
Firebase
accept-ranges: bytes
cache-control: max-age=3600
content-encoding: gzip
content-length: 3686565
content-type: audio/mpeg
date: Mon, 07 Oct 2019 11:47:43 GMT
etag: 267d9ec42517198c01e2cad893f1b14662a2d91904bc517aeda244c30358457c
last-modified: Mon, 07 Oct 2019 03:48:25 PDT
status: 200
strict-transport-security: max-age=31556926; includeSubDomains; preload
vary: x-fh-requested-host, accept-encoding
x-cache: MISS
x-cache-hits: 0
x-served-by: cache-lhr7363-LHR
x-timer: S1570448862.315027,VS0,VE1472
Firefox 在这两种情况下都能正常工作。
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0
代码
您可以在此处找到测试应用程序的代码,包括对测试设置、预期和结果的完整描述:
https://github.com/daffinm/audio-cache-test
如果您想查看,该应用目前已部署在 Firebase 上:
https://daffinm-test.firebaseapp.com/
问题
有没有人知道这里发生了什么以及为什么带有范围请求路由器的 pre-cached 音频无法在 Chrome 中播放?这是 Chrome 错误 and/or Workbox mis-configuration and/or Firebase 配置问题 - 还是完全不同的问题? (我已经联系了 Firebase 支持,他们非常有帮助,但目前无法启发我)。
存在Vary
header in the Firebase responses sounds like the culprit. By default, the Cache Storage API will use the Vary
header when determining whether or not there's a cache match. You can override this default behavior by passing in {ignoreVary: true}
when querying the Cache Storage API. Workbox supports this as an option you can provide when creating your strategy, via the matchOptions
parameter。
看起来你是 already passing in ignoreSearch: true
,所以你可以在旁边加上 ignoreVary: true
。
背景
我创建了一个 PWA 测试项目来了解如何让音频缓存与 Workbox 一起工作, 包括 scrub/seek 使用 range requests plugin.
我希望该应用预缓存所有音频,并使该音频可以离线播放,包括 scrub/seek。
Pre-caching 音频可以通过以下两种方式之一完成:
- 使用 Workbox injectManifest.
- 通过使用
cache.add(URL)
手动将音频文件添加到缓存
但是使用第一种方法 (injectManifest) 缓存的音频文件不会 scrub/seek 因为 Workbox pre-cache 不会 支持范围请求 headers。所以你需要在前面放一个启用范围请求的路由器 pre-cache 对于音频文件,如果您希望能够在缓存的音频文件中擦除 through/seek。
问题
Pre-cached 启用范围请求的音频将播放,并且 scrub/seek 在 Chrome 和 Firefox 中正常播放应用程序 来自 localhost 但在 Chrome 从 Firebase 提供时无法播放。
我看到所有 pre-cached 前面有范围请求路由器的音频文件都出现同样的错误:
Router is responding to: /media/audio/auto-pre-cached.mp3
Using CacheOnly to respond to '/media/audio/auto-pre-cached.mp3'
No response found in the 'act-auto-pre-cache-wbv4.3.1-actv0.0.1' cache.
The FetchEvent for "https://daffinm-test.firebaseapp.com/media/audio/auto-pre-cached.mp3" resulted in a network error response: the promise was rejected.
CacheOnly.mjs:115 Uncaught (in promise) no-response: The strategy could not generate a response for 'https://daffinm-test.firebaseapp.com/media/audio/auto-pre-cached.mp3'.
at CacheOnly.makeRequest (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-strategies.dev.js:343:15)
Chrome 尝试过的版本:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
这些文件存在于 Workbox 缓存中。我在 locahost 和 Firebase 之间看到的唯一区别是缓存响应 headers:
本地主机
cache-control: max-age=3600
content-length: 3770956
content-type: audio/mpeg; charset=utf-8
Date: Mon, 07 Oct 2019 09:37:03 GMT
etag: "12456134-3770956-"2019-09-29T20:05:00.314Z""
last-modified: Sun, 29 Sep 2019 20:05:00 GMT
server: ecstatic-2.2.2
Firebase
accept-ranges: bytes
cache-control: max-age=3600
content-encoding: gzip
content-length: 3686565
content-type: audio/mpeg
date: Mon, 07 Oct 2019 11:47:43 GMT
etag: 267d9ec42517198c01e2cad893f1b14662a2d91904bc517aeda244c30358457c
last-modified: Mon, 07 Oct 2019 03:48:25 PDT
status: 200
strict-transport-security: max-age=31556926; includeSubDomains; preload
vary: x-fh-requested-host, accept-encoding
x-cache: MISS
x-cache-hits: 0
x-served-by: cache-lhr7363-LHR
x-timer: S1570448862.315027,VS0,VE1472
Firefox 在这两种情况下都能正常工作。
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0
代码
您可以在此处找到测试应用程序的代码,包括对测试设置、预期和结果的完整描述:
https://github.com/daffinm/audio-cache-test
如果您想查看,该应用目前已部署在 Firebase 上:
https://daffinm-test.firebaseapp.com/
问题
有没有人知道这里发生了什么以及为什么带有范围请求路由器的 pre-cached 音频无法在 Chrome 中播放?这是 Chrome 错误 and/or Workbox mis-configuration and/or Firebase 配置问题 - 还是完全不同的问题? (我已经联系了 Firebase 支持,他们非常有帮助,但目前无法启发我)。
存在Vary
header in the Firebase responses sounds like the culprit. By default, the Cache Storage API will use the Vary
header when determining whether or not there's a cache match. You can override this default behavior by passing in {ignoreVary: true}
when querying the Cache Storage API. Workbox supports this as an option you can provide when creating your strategy, via the matchOptions
parameter。
看起来你是 already passing in ignoreSearch: true
,所以你可以在旁边加上 ignoreVary: true
。