【问题标题】:Angular service worker with @angular/pwa package showing `HTTP error 504` when offline带有@angular/pwa 包的 Angular 服务工作者在离线时显示“HTTP 错误 504”
【发布时间】:2020-09-24 13:01:58
【问题描述】:

我正在开发一个有角度的 PWA 应用程序。所以我通过ng add @angular/pwa添加了一个npm包。它添加成功,没有错误。

生成的清单工作正常。但我面临着服务人员的问题。当应用程序上线时,它会存储所有缓存(见附件),但每当应用程序下线时,它会显示错误 - HTTP ERROR 504

,而不是服务于 service worker 的请求

这是我的 ngsw-config.json -

   {
    "index": "/index.html",
    "assetGroups": [
      {
        "name": "app",
        "installMode": "prefetch",
        "resources": {
          "files": ["assets/images/favicon.ico", "/index.html", "/*.css", "/*.js"]
        }
      },
      {
        "name": "assets",
        "installMode": "lazy",
        "updateMode": "prefetch",
        "resources": {
          "files": [
            "/assets/**",
            "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
          ]
        }
      }
    ]
  }

任何帮助将不胜感激...

【问题讨论】:

  • 我认为您一切正常。根据 http 错误 (504),您的问题可能与您托管 pwa 的位置有关。因此,基本上,您与服务器的连接已正确执行,但您的服务器在尝试为您的 pwa 提供服务时却没有找到任何东西。总之,服务器正在使用某种中间件(例如 nginx),这就是浏览器没有部署缓存的原因,因为您的浏览器建立了连接并且不需要离线缓存。
  • 是的,此应用程序部署在 Nginx 服务器上。你能详细说明一下这个问题吗?
  • 好的,我会尽力的。基本上,实际上有两个连接,第一个是在你的浏览器和 nginx 代理之间,这个连接是正确执行的,所以你的浏览器不需要部署缓存版本。问题是第二个,连接断开(因为您正在检查离线功能)。也许,为了检查我是否正确,您可以执行两个快速测试。在本地部署并使用您的机器作为服务器测试离线功能或关闭 nginx 代理并检查它。
  • 好的,非常感谢@JTejedor,我会试试你的解决方案。 :)

标签: angular google-chrome angular-service-worker http-status-code-504 angular-pwa


【解决方案1】:

正如我们所评论的,您的问题与您的网络服务器或代理 nginx 有关。由于您与 nginx 正确连接,因此您的浏览器中未启用 PWA 离线功能。在了解了您的问题后,我发现了一些您将在 nginx 中使用的配置,以允许 PWA 在离线情况下正常运行。

google developers 中,您可以在 nginx 配置文件中添加这些行,以允许 PWA 行为:

location ~* (service-worker\.js)$ {
  # tells browsers the service worker scope
  add_header 'Service-Worker-Allowed' '/app';
}

我还在 the Philip Heltweg blog 中找到了这个配置文件,以允许 PWA 的完整行为。

server {
    listen 80;
    server_name _;

    gzip on;
    gzip_types text/html text/css application/javascript;

    root /var/www/;
    index index.html;

    # Force all paths to load either itself (js files) or go through index.html.
    location /index.html {
        try_files $uri /index.html;

        add_header Cache-Control "no-store, no-cache, must-revalidate";    
    }

    location / {
        try_files $uri /index.html;

        expires 1y;
        add_header Cache-Control "public";
    }
}

好吧,最后,我找到了一个有趣的 docker,如果你愿意使用 docker(当然),以简单的方式运行一个配置正确的 nginx Web 服务器。 Check this out.

我希望这三种不同的方法可以解决您的问题。如果我能提供更多帮助,请告诉我!

【讨论】:

  • @谢谢兄弟,我会检查你所有的解决方案。如果需要更多帮助,我会与您联系。
【解决方案2】:

为什么会出现错误 504?

504 错误不是来自您的服务器,而是来自充当代理的 Service Worker。

您在 PWA 中发出的每个 HTTP 请求都会通过 Service Worker (SW),可能会发生两件事:

  • 如果请求的资源在 SW 缓存上,则返回缓存的内容
  • 如果请求的资源不在 SW 缓存中,则 SW 向服务器执行请求

因此,如果您处于离线状态并且资源不在 SW 缓存中,则 SW 将尝试向服务器发出请求,但是,当您处于离线状态时,该请求将失败并且 SW 将返回 504 错误.您可以在您发布的最后一张图片中看到这实际上正在发生:顶部的 http 响应是您从 SW 获得的带有错误 504 的响应,而下面的请求(请参见左侧的轮子图标)是 SW 执行的请求到服务器并失败。

为什么缓存不匹配?

现在,您可能想知道,为什么 SW 没有在其缓存中找到资源?

嗯,Angular Service Worker 是一个很棒的工具,但它非常敏感,只要稍加改动,它就会失效。您需要知道的第一件事是它使用的缓存机制。基本上,当您构建 Angular 应用程序时,所有生成的文件都有一个关联的哈希值,该哈希值是用每个文件的内容计算的(检查生成的 ngsw.json 文件)。当您的应用运行时,软件会将此哈希(在编译时计算)与请求资源的哈希(在运行时计算)进行比较。

许多用户报告此机制存在问题,一些常见原因是:

  • 缩小/丑化 JS、CSS 和 HTML 文件的中间服务(例如 Cloudflare)
  • 部署管道上修改某些文件的自动化脚本
  • 以文本模式而非二进制模式传输文件的 FTP 客户端(例如 FileZilla)(更改其编码、行尾等)

所有这些都会对文件内容产生变化,因此软件将计算与编译时计算的哈希值不同的哈希值。这将导致缓存不匹配,您的应用将无法离线运行(您将收到 http 504 响应)。

附加信息

请注意,有些用户报告说该应用有时可以离线运行或在某些特定浏览器中运行。一种可能的解释是,在这些情况下,是浏览器级缓存机制起作用,而不是 SW 缓存本身。

进一步debug the Angular SW,您可以在/ngsw/state查看其自托管调试页面。

我建议您阅读documentation of the Angular service workerthis discussion

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 2022-10-20
    相关资源
    最近更新 更多