pwa на Chrome Mobile продолжает возвращать только кэшированную версию данных http ответов - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть прогрессивное веб-приложение Angular 7 (PWA, Service Worker).

Мое приложение отправляет http запросы к API для получения данных для страницы. вместе со служащим я кеширую данные, чтобы в следующий раз, когда пользователь зашел на страницу, он видел кэшированные данные до тех пор, пока не получит самые последние данные из ответа http.

Проблема в Chrome Mobile на Android. Он продолжает возвращать только кэшированный HTTP-ответ, а не новые данные. Все остальные браузеры и ОС возвращают новые данные.

Вот мой файл ngsw.json:

{
  "configVersion": 1,
  "timestamp": 1553131016147,
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "updateMode": "prefetch",
      "urls": [
        "/favicon.ico",
        "/index.html",
        "/main.888b10bbc9ea06b8a9bf.js",
        "/polyfills.9f595158f842acad6b37.js",
        "/runtime.2f29e12616932f0ed037.js",
        "/styles.d2478451b17ed7e705c5.css"
      ],
      "patterns": []
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "urls": [],
      "patterns": [
        "https:\\/\\/maxcdn\\.bootstrapcdn\\.com\\/font-awesome\\/4\\.7\\.0\\/css\\/font-awesome\\.min\\.css"
      ]
    }
  ],
  "dataGroups": [
    {
      "name": "api",
      "patterns": [
        "\\/api"
      ],
      "strategy": "freshness",
      "maxSize": 100,
      "maxAge": 259200000,
      "timeoutMs": 5000,
      "version": 1
    }
  ],
  "hashTable": {
    "/favicon.ico": "7c6a9b4e1370b6ee9386e16fba9ca4738b9e7037",
    "/index.html": "fdf70f70c0f37aaa11b990ac0cf32839480b69a4",
    "/main.888b10bbc9ea06b8a9bf.js": "abcc804a2ffbd57187d759a7c18b82963ac03d8c",
    "/polyfills.9f595158f842acad6b37.js": "4eb96258211620bfe371478144b69844117f5120",
    "/runtime.2f29e12616932f0ed037.js": "21109b3561b5a6c3ed51bc3015962f05da8e57b3",
    "/styles.d2478451b17ed7e705c5.css": "29fb80dd9fc36fbb4ee107f15fd24dd7400ea255"
  },
  "navigationUrls": [
    {
      "positive": true,
      "regex": "^\\/.*$"
    },
    {
      "positive": false,
      "regex": "^\\/(?:.+\\/)?[^/]*\\.[^/]*$"
    },
    {
      "positive": false,
      "regex": "^\\/(?:.+\\/)?[^/]*__[^/]*$"
    },
    {
      "positive": false,
      "regex": "^\\/(?:.+\\/)?[^/]*__[^/]*\\/.*$"
    }
  ]
}

Соответствующая часть кода находится в dataGroups, все URL с префиксом /api, и, как вы можете видеть, я использую стратегию freshness, которая согласно странице конфигурации рабочего сервиса Angular: https://angular.io/guide/service-worker-config

свежесть оптимизирует для валюты данных, преимущественно выборки запрашиваемые данные из сети. Только если время ожидания в сети, согласно таймауту, запрос возвращается в кеш. Это полезно для ресурсов, которые часто меняются; например, аккаунт противовесов.

но, похоже, в этом случае Chrome Mobile на Android происходит обратное.

Кто-нибудь из вас сталкивался с этим и может указать мне правильное направление?

1 Ответ

0 голосов
/ 18 апреля 2019

Из того, что я понимаю о том, как работают угловые работники сферы обслуживания:

Если вы указали стратегию freshness, то работник службы будет ждать в течение времени, указанного с помощью клавиши timeout (не timeoutMs), сеть ответит, если сеть не отвечает в течение указанного времени, ответ будет отправляется из кэшированных данных работником службы.

В вашем случае устройство Android может иметь меньшую скорость интернета, поэтому данные не будут получены в течение указанного интервала времени ожидания, поэтому вы получите кэшированные данные. Проверьте приложение, увеличив время ожидания.


На всякий случай, если вам это нужно.

Я нахожу запросы кеширования API очень ненадежными, у меня не было четкого представления, когда я точно получу обновленные данные. (Да, когда maxSize или maxAge превышают указанные значения или превышено время ожидания, но все еще нет четкого способа, которым я мог бы точно получить свежие данные.).

Всякий раз, когда я хотел получить свежие данные с сервера, я очищал все затем кэшированные данные из браузера, которые принадлежали ngsw вызовам API. У меня был этот сценарий, написанный для того же. Посмотрите, если вам это нужно.

caches.keys().then((keys) => {
    keys.forEach((eachCacheName) => {
        let regExPat = /^(ngsw).*api.*/;
        if (regExPat.test(eachCacheName)) {
            caches.open(eachCacheName).then((eachCache) => {
                eachCache.keys().then((requests) => {
                    requests.forEach((eachRequest) => { eachCache.delete(eachRequest); });
                });
            });
        }
    });
});
...