当从 Firebase 提供服务时,带有范围请求路由器的 Workbox 预缓存音频无法在 Chrome 中播放

daf*_*inm 3 google-chrome html5-audio firebase-hosting progressive-web-apps workbox

背景

我创建了一个 PWA 测试项目,以了解如何使用Workbox进行音频缓存,包括使用范围请求插件进行清理/查找。

我希望应用程序预先缓存所有音频,并使该音频可以离线播放,包括擦洗/搜索。

预缓存音频可以通过以下两种方式之一完成:

  1. 使用Workbox insertManifest
  2. 通过手动将音频文件添加到缓存中cache.add(URL)

但使用第一种方法 (injectManifest) 缓存的音频文件不会擦除/查找,因为 Workbox 预缓存不支持范围请求标头。因此,如果您希望能够在缓存的音频文件中进行清理/查找,则需要在音频文件的预缓存前面放置一个启用范围请求的路由器。

问题

当应用程序从本地主机提供服务时,启用了范围请求的路由器的预缓存音频将在 Chrome 和 Firefox 中正常播放和擦除/搜索,但当从 Firebase 提供服务时,则无法在 Chrome 中播放。

对于前面有范围请求路由器预缓存的所有音频文件,我看到相同的错误:

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)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这些文件存在于 Workbox 缓存中。我可以看到 locahost 和 Firebase 之间的唯一区别在于缓存的响应标头:

本地主机

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
Run Code Online (Sandbox Code Playgroud)

火力基地

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
Run Code Online (Sandbox Code Playgroud)

Firefox 在这两种情况下都可以正常工作。

Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0
Run Code Online (Sandbox Code Playgroud)

代码

您可以在此处找到测试应用程序的代码,包括测试设置、期望和结果的完整描述:

https://github.com/daffinm/audio-cache-test

如果您想查看一下,该应用程序目前已部署在 Firebase 上:

https://daffinm-test.firebaseapp.com/

问题

有谁知道这里发生了什么以及为什么带有范围请求路由器的预缓存音频无法在 Chrome 中播放?这是 Chrome 错误和/或 Workbox 配置错误和/或 Firebase 配置问题 - 还是完全不同的问题?(我已联系 Firebase 支持人员,他们非常有帮助,但目前无法启发我)。

Jef*_*ick 5

VaryFirebase 响应中标头的存在听起来像是罪魁祸首。默认情况下,缓存存储 API 将Vary在确定是否存在缓存匹配时使用标头。{ignoreVary: true}您可以通过在查询缓存存储 API 时传入来覆盖此默认行为。Workbox支持此选项,您可以在创建策略时通过matchOptions参数提供此选项。

看起来您已经传递了ignoreSearch: true,因此您可以ignoreVary: true在旁边添加。