本文介绍了Angular7:Service Worker 未按预期运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Angular Service Worker,我缓存了声音(mp3 文件),以便可以离线播放.这是ngsw-config-json:

I have an angular service worker and I have cached sounds (mp3 files) so that they can be played offline. Here is the ngsw-config-json:

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
        "/favicon.ico",
        "/index.html",
        "/*.css",
        "/*.js",
        "/*.svg",
        "/*.eot",
        "/*.woff",
        "/*.woff2",
        "/*.tff"
      ]
    }
  }, {
    "name": "assets",
    "installMode": "prefetch",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/sounds/character1/**",
        "/assets/sounds/character2/**"
      ]
    }
  }]
}

在我的网络应用中,声音是这样播放的:

In my web app, the sounds play like this:

let audioLink = `/assets/sounds/${character}/${soundURL}`;
let player = new Audio(audioLink);
player.play()

该网站可离线使用.HTML、CSS、JS、JSON 文件都被缓存.但是声音没有播放(当我尝试播放时,给出了我上面显示的错误).

The website works offline. The HTML, CSS, JS, JSON files are all being cached. But the sounds don't play (when I try playing, the give an error I showed above).

在 Chrome 开发者工具 > 应用程序 > 缓存中,我可以看到有一些声音(路径),但不是全部.但是没有离线工作.

In the Chrome Developer Tools > Application > Cache, I can see that a few of the sounds are there (the paths), but not all. But none of them are working offline.

有时会出现这些错误:

  • GET "path/to/file" net::ERR_ABORTED 504(网关超时)
  • 未捕获(承诺)DOMException
  • 加载资源失败:net::ERR_INTERNET_DISCONNECTED

它有时也说 manifest.json 有问题,但没有任何问题,因为它在线时显示在开发人员工具的清单部分.

It sometimes also says there is a problem with the manifest.json, but there is nothing wrong as it shows up in the manifest section of the developer tools when online.

有没有办法解决这个问题?这不是 Chrome 错误,因为我在 Safari 和 Firefox 中也看到了相同的行为.我知道在新的 chrome 版本中存在一个错误,并且由于这个错误,favicon.ico 不会离线显示

Is there any fix to this problem? It's not a Chrome bug, because I am seeing the same behavior in Safari and Firefox too. I know that there is a bug in a new chrome version, and because of this bug, the favicon.ico does not show up offline

不确定这是否会有所帮助,但此处是托管 Web 应用程序的链接.如果您在 Chrome 开发者工具中看到网络选项卡,您可以看到 mp3 文件正在下载",但不能离线播放.

Not sure if this will help, but here is the link to the hosted web application. If you see the network tab in the Chrome Developer Tools, you can see that the mp3 files are 'downloading', but they don't play offline.

在生成用于生产的网站 (ng build --prod --base-href="/") 后,我查看了 ngsw.json,这是我看到的(删除了一些行):

After generating the website for production (ng build --prod --base-href="/"), I looked into the ngsw.json and this is what I saw (some lines removed):

{
  "name": "assets",
  "installMode": "prefetch",
  "updateMode": "prefetch",
  "urls": [
    "/assets/sounds/character1/sound one.mp3",
    "/assets/sounds/character1/sound two.mp3",
    "/assets/sounds/character2/sound three.mp3"
    "/assets/sounds/character2/sound four.mp3"
  ],
  "patterns": []
}

这里是完整生成的ngsw.json.一切都已设置为预缓存,而不是延迟缓存.

Here is the full generated ngsw.json. Everything has been set to precache rather than cache lazily.

并且所有这些资产 URL 也在 "hashTable" 对象中.我也在 chrome 开发者工具(开发者工具 > 网络)中看到它们被下载,但我只在应用程序缓存部分看到其中的一些(可能是总共 150 个中的前 20-30 个).

And all these asset URLs are also in the "hashTable" object. I also see them being downloaded in the chrome developer tools (developer tools > network), but I only see some of them in the application cache section (maybe the first 20-30 out of 150 in total).

我在这里做错了什么?这可能是 Angular 7 的错误吗?我已经看到有关类似问题的各种其他 StackOverflow 和 Reddit 问题.

What am I doing wrong here? Could this possible be an Angular 7 bug? I've seen various other StackOverflow and Reddit questions about a similar issue.

我尝试过的东西正在改变

Something I tried was changing

let audioLink = `/assets/sounds/${character}/${soundURL}`;

let audioLink = `assets/sounds/${character}/${soundURL}`;

(删除开头的斜杠),但这并没有什么区别.

(removed slash at the start), but that didn't make a difference.

我完全确定所有声音文件路径都是正确的,因为网站在线运行时绝对没有错误.

I am completely sure that all the sound file paths are correct because there are abolutely no errors when the site is running online.

除上述之外,我尝试手动更改所有网址并将 %20 插入到应该有空格的位置.例如,将 "/assets/sounds/character1/sound one.mp3" 更改为 "/assets/sounds/character1/sound%20one.mp3",但确实如此也不行.

Apart from the above, I tried manually changing all the urls and inserting %20 where there was supposed to be a space. For example, changing "/assets/sounds/character1/sound one.mp3" to "/assets/sounds/character1/sound%20one.mp3", but that did not work either.

我注意到的一件事是,如果您是第一次访问该网站,并等待所有声音下载完毕,之后就变得不重要了,关闭您的互联网连接并试用该网站,所有声音都可以正常工作.但只有一段时间,通常大约 10-15 分钟,然后他们停止工作.我已经在 Chrome、Chrome Android、Firefox、Safari 和 IOS Safari 上进行了测试.

One thing I've noticed is that if you visit the website for the first time, and wait for all the sounds to download, then immateriality after, close your internet connection and try out the site, all the sounds work. But only for some time usually around 10-15 minutes then they stop working. I have tested on Chrome, Chrome Android, Firefox, Safari, and IOS Safari.

根据某人的建议,我尝试更改

As suggested by someone, I tried changing

{
  "name": "assets",
  "installMode": "prefetch",
  "updateMode": "prefetch",
  "urls": [
    "/assets/sounds/character1/sound one.mp3",
    "/assets/sounds/character1/sound two.mp3",
    "/assets/sounds/character2/sound three.mp3"
    "/assets/sounds/character2/sound four.mp3"
  ],
  "patterns": []
}

{
  "name": "assets",
  "installMode": "prefetch",
  "updateMode": "prefetch",
  "urls": [
    "/assets/sounds/**"
  ],
  "patterns": []
}

但同样的问题仍然存在:声音被离线缓存了大约 10-15 分钟,之后它们不会离线播放.我只能在 Chrome 和 Chrome Android 中对此进行测试.

but the same problem persists: the sounds are cached offline for maybe 10-15 minutes, after which they do not play offline. I was only able to test this in Chrome and Chrome Android.

推荐答案

我在@codeninja 的帮助下找到了我的问题的答案.

I found an answer to my question with the help of @codeninja.

首先,audioLink 必须是指向声音的直接链接.我在 Github 上托管该网站,因此链接如下所示:

Firstly, the audioLink has to be a direct link to the sound. I'm hosting the site on Github, so the link looks something like this:

let url = `sounds/path_to_sound.mp3`
let audioLink = `https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/${url}`;

其次,我们不能只使用 sound.play()Audio() 方法,我们必须使用 HttpClient 检索音频.我不确定究竟是为什么,但 codeninja 建议 ngsw 缓存文件的方式与 Audio 类不兼容.我不确定这是否属实,但我发现离线时,我必须使用 HttpClient 来检索音频 blob(如下所示).如果没有,您会收到 response not Ok 错误.即使我给了直接链接https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/direct.mp3,它也会抛出同样的错误.

Secondly, we cannot just use the sound.play() with Audio() method, we must retrieve the audio using HttpClient. I am not sure why exactly, but codeninja suggested that the way ngsw caches files is incompatible with the Audio class. I'm not sure if this is true, but I found that when offline, I had to use the HttpClient to retrieve the audio blob (demonstrated below). If not, you get a response not Ok error. Even if I gave the direct link https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/direct.mp3, it would throw the same error.

总而言之,代码如下所示:

All in all, the code looks like this:

首先有一个 getSound() 函数:

getSound(url) {
  return this.http.get(url, {responseType: 'blob'});
}

然后在另一个函数(playSound(url))中,我们有:

Then in another function (playSound(url)), we have this:

playSound(url) {
  let audioLink = `https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/${url}`;

  this.getSound(audioLink)
    .subscribe(data => {
      console.log(data);
      // data is an audio blob
      let url = URL.createObjectURL(data);

      let sound = document.createElement('audio');
      sound.src = url;
      sound.play();
    })
}

此外,我还必须更改我的 ngsw-config.json.我只更改了资产"部分,所以我会证明:

Additionally, I also had to change my ngsw-config.json. I only changed the "assets" part so I'll show that:

{
  "name": "assets",
  "installMode": "lazy",
  "updateMode": "prefetch",
  "resources": {
    "files": [
    ],
    "urls": [
       "https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/**"
    ]
  }
}

我也无法让它与预取"一起工作.虽然缓存的声音现在可以离线播放,但它们只会在之前播放过的情况下播放,因为它被设置为懒惰".

I was also unable to get it to work with "prefetch". Although the cached sounds now play offline, they will only play if they have been played before, as it is set to "lazy".

我在 Chrome、Chrome Android 和 Firefox 上测试了此解决方案,并且运行良好.

I tested this solution on Chrome, Chrome Android, and Firefox, and it is working fine.

这篇关于Angular7:Service Worker 未按预期运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 12:54