Поделиться через


Прогрессивное веб-приложение (PWA) Blazor ASP .NET Core

Примечание.

Это не последняя версия этой статьи. Для текущего релиза смотрите версию этой статьи .NET 9.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. Для текущего релиза смотрите версию этой статьи .NET 9.

Внимание

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

Для текущего релиза смотрите версию этой статьи .NET 9.

Прогрессивное веб-приложение Blazor — это одностраничное приложение (SPA), которое использует API и функциональные возможности современного браузера, реализуя свойственное классическим приложениям поведение.

Blazor WebAssembly — это стандартная клиентская платформа веб-приложений, которая поддерживает API любых браузеров, в том числе API прогрессивных веб-приложений (PWA), требуемых для реализации следующих возможностей.

  • работа в автономном режиме и мгновенная загрузка вне зависимости от скорости сети;
  • возможность запуска в отдельном окне приложения, а не только в окне браузера;
  • Запускается из меню «Пуск» операционной системы хоста, дока или начального экрана.
  • получение push-уведомлений от внутреннего сервера, даже если пользователь не работает с приложением;
  • автоматическое обновление в фоновом режиме.

Слово прогрессивное используется для описания таких приложений по следующим причинам:

  • на начальном этапе пользователь может открывать и использовать приложение в своем веб-браузере аналогично любому другому одностраничному приложению;
  • затем его можно установить в своей ОС и включить push-уведомления.

Создание проекта на основе шаблона PWA

При создании приложения Blazor WebAssembly установите флажок Прогрессивное веб-приложение.

При необходимости PWA можно настроить для приложения, созданного из шаблона проекта ASP.NET Core HostedBlazor WebAssembly . Сценарий прогрессивного веб-приложения не зависит от модели размещения.

Преобразование существующего приложения Blazor WebAssembly в PWA

В этом разделе приводятся указания по преобразованию существующего приложения Blazor WebAssembly в PWA.

В файле проекта приложения сделайте следующее:

  • Добавьте указанное ниже свойство ServiceWorkerAssetsManifest в PropertyGroup:

      ...
      <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
    </PropertyGroup>
    
  • Добавьте указанный ниже элемент ServiceWorker в ItemGroup:

    <ItemGroup>
      <ServiceWorker Include="wwwroot\service-worker.js" 
        PublishedContent="wwwroot\service-worker.published.js" />
    </ItemGroup>
    

Для получения статических ресурсов воспользуйтесь одним из следующих подходов:

  • Создайте отдельный новый проект PWA с помощью команды dotnet new в командной оболочке:

    dotnet new blazorwasm -o MyBlazorPwa --pwa
    

    В предыдущей команде параметр -o|--output создает новую папку для приложения с именем MyBlazorPwa.

    Если вы не преобразуете приложение для использования в последнем выпуске, передайте параметр -f|--framework. В следующем примере создается приложение для .NET 5:

    dotnet new blazorwasm -o MyBlazorPwa --pwa -f net5.0
    
  • Перейдите по приведенному ниже URL-адресу в репозиторий GitHub для ASP.NET Core, который содержит ссылки на справочные материалы и ресурсы для ветви main. Выберите выпуск, с которым вы работаете, в раскрывающемся списке Switch branches or tags, который подходит для вашего приложения.

    Blazor WebAssembly Папка шаблона wwwroot проекта (dotnet/aspnetcore ветвь репозитория main GitHub)

    Примечание.

    Ссылки в документации на исходный код .NET обычно загружают ветку репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

    Скопируйте следующие файлы из папки wwwroot источника в созданном вами приложении или из справочных ресурсов в репозитории GitHub dotnet/aspnetcore в папку wwwroot приложения:

    • icon-192.png
    • icon-512.png
    • manifest.webmanifest
    • service-worker.js
    • service-worker.published.js

В файле wwwroot/index.html приложения:

  • Добавьте элементы <link> для манифеста и значка приложения:

    <link href="manifest.webmanifest" rel="manifest" />
    <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
    <link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
    
  • Перейдите к репозиторию ASP.NET Core GitHub по следующему URL-адресу, который ссылается на v7.0.0 источник и ресурсы тега. Если вы используете .NET 8 или более поздней версии, измените селектор версии документа в верхней части этой статьи, чтобы просмотреть обновленные рекомендации для этого раздела. Выберите выпуск, с которым вы работаете, в раскрывающемся списке Switch branches or tags, который подходит для вашего приложения.

    Blazor WebAssembly Папка шаблона wwwroot проекта (v7.0.0 тег)

    Примечание.

    Ссылки в документации на исходный код .NET обычно загружают ветку репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

    Скопируйте следующие файлы из папки wwwroot источника в созданном вами приложении или из справочных ресурсов в репозитории GitHub dotnet/aspnetcore в папку wwwroot приложения:

    • favicon.png
    • icon-192.png
    • icon-512.png
    • manifest.json
    • service-worker.js
    • service-worker.published.js

В файле wwwroot/index.html приложения:

  • Добавьте элементы <link> для манифеста и значка приложения:

    <link href="manifest.json" rel="manifest" />
    <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
    <link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
    
  • Добавьте следующий тег <script> в закрывающий тег </body> сразу после тега скрипта blazor.webassembly.js:

        ...
        <script>navigator.serviceWorker.register('service-worker.js');</script>
    </body>
    

Установка и манифест приложения

При посещении приложения, созданного с помощью шаблона PWA, у пользователей есть возможность установки приложения в меню "Пуск", "Док-станция" или на начальном экране. Порядок применения этого параметра зависит от того, какой браузер используется. В классических версиях браузеров на основе Chromium, таких как Microsoft Edge или Chrome, в строке URL-адреса появляется кнопка Добавить. После того как пользователь нажмет кнопку Добавить, отобразится диалоговое окно подтверждения.

Диалоговое окно подтверждения в Google Chrome представляет кнопку

В iOS посетители могут установить прогрессивное веб-приложение с помощью кнопки Поделиться в браузере Safari, а также используя параметр Добавить на главный экран. В браузере Chrome для Android для этой цели следует нажать кнопку Меню в правом верхнем углу окна, а затем выбрать команду Добавить на экран Home.

После установки приложение будет открываться в отдельном окне без адресной строки.

Приложение MyBlazorPwa запускается в Google Chrome без адресной строки.

Чтобы настроить заголовок окна, цветовую схему, значок или другие сведения, используйте файл manifest.json в каталоге wwwroot проекта. Схема этого файла соответствует веб-стандартам. Для получения дополнительной информации см. веб-документацию MDN: Манифест веб-приложения.

Поддержка работы в автономном режиме

Приложения, созданные с помощью параметра шаблона PWA, поддерживают работу в автономном режиме. Для этого пользователь должен сначала посетить приложение при наличии подключения к сети. Браузер автоматически скачает и кэширует все ресурсы, необходимые для его работы в автономном режиме.

Внимание

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

Предупреждение

Если вы планируете распространять прогрессивное веб-приложение с поддержкой автономного режима, важно учесть несколько важных предупреждений и предостережений. Эти сценарии свойственны автономным прогрессивным веб-приложениям и не являются специфическими для Blazor. Не забудьте прочитать и понять эти предостережения, прежде чем делать предположения о том, как работает приложение с поддержкой автономного режима.

Чтобы увидеть, как работает поддержка автономного режима:

  1. Публикация приложения. Дополнительные сведения см. в статье Размещение и развертывание ASP.NET Core Blazor.

  2. Разверните приложение на сервере, который поддерживает протокол HTTPS, и получите доступ к приложению в браузере по его защищенному HTTPS-адресу.

  3. Откройте средства разработки браузера и убедитесь, что для узла на вкладке Приложение зарегистрирован Сервисный работник.

    Вкладка

  4. Перезагрузите страницу и просмотрите вкладку Сеть. Service Worker или кэш памяти перечислены в качестве источников для всех ресурсов страницы:

    Вкладка

  5. Чтобы убедиться, что для загрузки приложения браузеру не требуется доступ к сети:

    • Завершите работу веб-сервера и проверьте, как приложение продолжит работу в обычном режиме, включая перезагрузку страниц. Аналогичным образом приложение продолжает обычную работу при снижении скорости сетевого подключения.
    • Поручите браузеру имитировать работу в автономном режиме на вкладке Сеть.

    Вкладка

Поддержка автономного режима с помощью service worker является веб-стандартом, не относящимся к Blazor. Дополнительные сведения о сервисных работниках см. в веб-документации MDN: API сервисного работника. Дополнительные сведения о распространенных шаблонах работы для сервисных работников см. в Google Web: Жизненный цикл сервисного работника.

Шаблон PWA Blazor создает два файла служебного рабочего:

  • wwwroot/service-worker.js, который используется во время разработки;
  • wwwroot/service-worker.published.js, который используется после публикации приложения.

Чтобы поделиться логикой между двумя файлами рабочих служб, рассмотрите следующий подход.

  • Добавьте третий файл JavaScript для хранения общей логики.
  • Используйте self.importScripts, чтобы загрузить общую логику в оба файла service worker.

Стратегия кэширования с опережением

Встроенный service-worker.published.js service worker обрабатывает запросы с использованием стратегии кэш сначала. Это означает, что Service Worker предпочитает возврат содержимого из кэша, независимо от наличия у пользователя доступа к сети или доступности на сервере более нового содержимого.

Стратегия cache-first полезна по следующим причинам.

  • Во-первых, за счет этого повышается надежность. Состояние доступа к сети сложно определить однозначно, Пользователь не просто находится в сети или вне её:

    • Устройство пользователя может предположить, что оно подключено к сети, но скорость соединения может быть настолько низкой, что ожидание загрузки содержимого становится непрактичным.
    • В некоторых случаях сеть может возвращать некорректные результаты для URL-адресов, например, когда существует перенаправляющий портал Wi-Fi, блокирующий или перенаправляющий определенные запросы.

    Именно поэтому на API navigator.onLine браузера нельзя полагаться как на надежный инструмент.

  • Во-вторых, это позволяет гарантировать корректность. При создании кэша автономных ресурсов служебный работник использует хэширование содержимого, чтобы обеспечить получение полноценного и согласованного снимка состояния ресурсов в один конкретный момент времени. В дальнейшем этот кэш используется в качестве атомарной единицы. Запрашивать более новые версии ресурсов из сети нецелесообразно, поскольку все данные, которые требуются, уже хранятся в кэше. Любые другие данные могут стать причиной несогласованности и несовместимости, например при попытке использовать версии сборок .NET, которые не компилировались вместе.

Если необходимо запретить браузеру получение service-worker-assets.js из его HTTP-кэша, например, чтобы устранить временные ошибки проверки целостности при развертывании новой версии сервисного работника, обновите регистрацию сервисного работника в wwwroot/index.html, установив значение updateViaCache на 'none':

<script>
  navigator.serviceWorker.register('/service-worker.js', {updateViaCache: 'none'});
</script>

Обновления в фоновом режиме

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

Шаблон прогрессивного веб-приложения Blazor создаёт приложения, которые автоматически пытаются обновиться в фоновом режиме, когда пользователь посещает их и имеет работающее сетевое подключение. Этот процесс реализуется следующим образом:

  • Во время компиляции проект создает манифест рабочих ресурсов службы, который называется service-worker-assets.js. Манифест перечисляет все статические ресурсы, которые требуются для работы приложения в автономном режиме, например, сборки .NET, файлы JavaScript и каскадные таблицы стилей, в том числе хэши содержимого. Служебный работник загружает список ресурсов, чтобы знать, какие ресурсы нужно кэшировать.
  • Каждый раз, когда пользователь открывает приложение, браузер повторно запрашивает service-worker.js и service-worker-assets.js в фоновом режиме. Файлы сравниваются побайтово с существующей установленной рабочей ролью службы. Если сервер возвращает измененное содержимое для любого из этих файлов, служебный работник пытается установить новую версию самого себя.
  • При установке собственной новой версии рабочая роль службы создает новый отдельный кэш для автономных ресурсов и начинает заполнять кэш ресурсами, перечисленными в файле service-worker-assets.js. Эта логика реализуется в функции onInstall в файле service-worker.published.js.
  • Процесс завершается успешно, когда все ресурсы загружаются без ошибок и все хэши содержимого совпадают. В случае успешного выполнения новый служебный работник переходит в состояние ожидания активации. Как только пользователь закроет приложение (т. е. все вкладки или окна, в которых оно отображается), новая рабочая роль службы становится активной и используется при последующем посещении приложения. Старый служебный обработчик и его кэш удаляются.
  • Если процесс завершается неудачно, новый экземпляр рабочей роли службы отклоняется. При следующем посещении пользователя будет предпринята попытка выполнить процесс обновления еще раз в расчете на более высокое качество сетевого подключения и возможность выполнения необходимых запросов.

Настроить этот процесс можно, используя логику рабочей роли службы. Все перечисленные выше варианты не являются специфичными для Blazor, однако описывают стандартный способ использования шаблона прогрессивного веб-приложения. Для получения дополнительной информации см. веб-документы MDN: API сервис-воркера.

Принципы разрешения запросов

Как описывается выше в разделе Стратегия первичного обращения к кэшу, по умолчанию рабочая роль службы применяет стратегию первичного обращения к кэшу, то есть пытается по возможности всегда использовать кэшированное содержимое. Если для определённого URL-адреса нет кэшированного содержимого, например, при запросе данных из серверного API, сервис-воркер возвращается к обычному сетевому запросу. Сетевой запрос выполняется успешно, если сервер доступен. Эта логика реализуется в функции onFetch в файле service-worker.published.js.

Если компоненты приложения Razor запрашивают данные из серверных API и вам требуется удобный пользовательский интерфейс для обработки сбоев, связанных с отсутствием доступа к сети, то соответствующую логику необходимо реализовать в самих компонентах приложения. Например, используйте try/catch для запросов HttpClient.

Поддержка страниц, рендерящихся на сервере

Рассмотрим, что происходит при первом переходе пользователя к URL-адресу, например к /counter, или по любой другой прямой ссылке в приложении. В таких случаях вам не нужно возвращать кэшированное содержимое как /counter. Вместо этого нужно загрузить в браузер содержимое, кэшированное как /index.html, для запуска приложения Blazor WebAssembly. Такие начальные запросы называются запросами навигации в отличие от следующих запросов:

  • запросы subresource на изображения, таблицы стилей или другие файлы.
  • fetch/XHR запросы для получения данных API.

В служебном скрипте по умолчанию содержится специальная логика для запросов на навигацию. Служебный работник обрабатывает запросы, возвращая кэшированное содержимое для /index.html, независимо от запрашиваемого URL. Эта логика реализуется в функции onFetch в файле service-worker.published.js.

Если для некоторых URL-адресов в вашем приложении должен возвращаться подготавливаемый к просмотру на сервере код HTML (то есть для обслуживания /index.html не должен использоваться кэш), вам потребуется изменить логику рабочей роли службы. Если все URL-адреса, содержащие /Identity/, требуется обрабатывать как обычные сетевые запросы к серверу, следует изменить логику функции service-worker.published.js в файле onFetch. Найдите следующий код:

const shouldServeIndexHtml = event.request.mode === 'navigate';

Измените код следующим образом:

const shouldServeIndexHtml = event.request.mode === 'navigate'
  && !event.request.url.includes('/Identity/');

Если этого не сделать, то, независимо от наличия сетевого подключения, сервисный работник будет перехватывать запросы к таким URL-адресам и разрешать их с помощью /index.html.

Добавьте дополнительные конечные точки для внешних поставщиков аутентификации в проверку. В следующем примере в проверку добавляется /signin-google для проверки подлинности Google:

const shouldServeIndexHtml = event.request.mode === 'navigate'
  && !event.request.url.includes('/Identity/')
  && !event.request.url.includes('/signin-google');

Для среды Development не требуется никаких действий, поскольку содержимое всегда извлекается из сети.

Управление кэшированием ресурсов

Если в вашем проекте определено свойство MSBuild ServiceWorkerAssetsManifest, средства сборки Blazor создадут манифест ресурсов для service worker с указанным именем. По умолчанию шаблон прогрессивного веб-приложения создает файл проекта со следующим свойством.

<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>

Этот файл помещается в выходной каталог wwwroot, откуда браузер может извлекать его посредством запроса /service-worker-assets.js. Чтобы просмотреть содержимое этого файла, откройте /bin/Debug/{TARGET FRAMEWORK}/wwwroot/service-worker-assets.js в текстовом редакторе. Не вносите изменения в этот файл, поскольку он создается заново при каждой сборке.

Манифест перечисляет:

  • Все управляемые Blazor ресурсы, в том числе сборки .NET и файлы среды выполнения .NET WebAssembly, которые требуются для работы в автономном режиме.
  • Все ресурсы, которые будут опубликованы в каталоге wwwroot приложения, такие как изображения, таблицы стилей и файлы JavaScript. К ним также относятся статические веб-ресурсы, предоставляемые в составе внешних проектов и пакетов NuGet.

Чтобы управлять тем, какие из этих ресурсов извлекаются и кэшируются служебным рабочим, измените логику в onInstall в service-worker.published.js. Служебный рабочий процесс извлекает и кэширует файлы, соответствующие типичным расширениям имен веб-файлов, таким как .html, .css, .js и .wasm, а также типы файлов, относящиеся к Blazor WebAssembly, такие как файлы .pdb (все версии) и файлы .dll (ASP.NET Core в .NET 7 или более ранней версии).

Чтобы включить другие ресурсы, отсутствующие в каталоге wwwroot приложения, определите дополнительные записи ItemGroup MSBuild, как показано в следующем примере.

<ItemGroup>
  <ServiceWorkerAssetsManifestItem Include="MyDirectory\AnotherFile.json"
    RelativePath="MyDirectory\AnotherFile.json" AssetUrl="files/AnotherFile.json" />
</ItemGroup>

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

Внимание

Добавление ServiceWorkerAssetsManifestItem не приводит к публикации файла в каталог wwwroot приложения. Выходные данные публикации следует контролировать отдельно. В манифесте ресурсов сервисного работника ServiceWorkerAssetsManifestItem только появляется дополнительная запись.

Push-уведомления

Как и любые аналоги, прогрессивные веб-приложения Blazor WebAssembly поддерживают получение push-уведомлений от внутреннего сервера. Сервер может отправлять такие уведомления в любое время, даже если приложение не используется активно (например, если другой пользователь выполняет действие, о котором требуется оповестить).

Предупреждения относительно прогрессивных веб-приложений с поддержкой автономной работы

Не всем приложениям следует пытаться поддерживать работу в автономном режиме. Поддержка оффлайн добавляет значительные сложности, которые не всегда оправданы для нужных случаев использования.

Офлайн поддержка обычно актуальна только:

  • Если основное хранилище данных находится локально в браузере. В качестве примера можно привести разработку пользовательского интерфейса для устройства Интернета вещей, которое хранит данные в localStorage или индексированной базе данных.
  • Приложение тратит значительный объем ресурсов на получение и кэширование данных серверного API для каждого пользователя, чтобы они могли работать с такими данными в автономном режиме. Если приложение должно поддерживать редактирование, потребуется создать систему, которая будет отслеживать изменения и синхронизировать их с серверной частью.
  • Необходимо гарантировать мгновенную загрузку приложения независимо от состояния сетевого подключения. Реализуйте подходящий пользовательский опыт вокруг запросов к серверному API, чтобы показывать их прогресс и корректно справляться с ситуациями, когда запросы не удаются из-за отсутствия сети.

Кроме того, поддержка работы в автономном режиме для прогрессивных веб-приложений сопряжена с рядом дополнительных сложностей. Разработчикам следует внимательно изучить предостережения, приведенные в разделах ниже.

Оффлайн-режим поддерживается только для опубликованных материалов

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

При создании приложения, которое поддерживает работу в автономном режиме, недостаточно просто тестировать его в среде Development. Вам придется проверить приложение в опубликованном состоянии, чтобы понять, как оно будет вести себя при различных состояниях сети.

Обновление завершается после перехода пользователя от приложения к другой задаче

Обновления будут выполняться только после того, как пользователь выйдет из приложения на всех вкладках. Как поясняется в разделе Обновления в фоновом режиме, после развертывания и обновления приложения браузер получит обновленные файлы рабочей роли службы, чтобы запустить процесс обновления.

Что удивляет многих разработчиков, так это то, что, даже когда это обновление завершается, оно не вступает в силу, пока пользователь не покинет все вкладки. Недостаточно обновить вкладку, отображающую приложение, даже если она является единственной вкладкой, отображающей приложение. До тех пор пока приложение полностью не закрыто, новый служебный работник остается в состоянии ожидания активации. Это не зависит Blazorот стандартного поведения веб-платформы.

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

Вкладка

Рабочая роль будет находиться в состоянии ожидания до тех пор, пока список "клиентов" (т. е. вкладок или окон, в которых отображается приложение) не опустеет. Это необходимо для обеспечения согласованности. Согласованность означает получение всех ресурсов из одного атомарного кэша.

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

Пользователи могут запускать любую ранее существовавшую версию приложения

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

Как описано в разделе "Фоновые обновления ", после развертывания обновления в приложении каждый существующий пользователь продолжает использовать предыдущую версию по крайней мере для одного дальнейшего посещения, так как обновление происходит в фоновом режиме и не активируется до тех пор, пока пользователь после этого не перейдет. Кроме того, в этом случае предыдущей используемой версией не обязательно будет та, которую вы развернули в прошлый раз. В зависимости от того, когда пользователь последний раз выполнял обновление, это может быть любая ранее существовавшая версия.

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

Соответственно, по возможности не следует развертывать существенные изменения в серверных API. Если это все же необходимо, рекомендуется использовать стандартные API сервис-воркеров, такие как ServiceWorkerRegistration, чтобы определить, актуальна ли версия приложения, и, если нет, предотвратить его использование.

Возникают помехи в работе подготавливаемых к просмотру на сервере страниц

В разделе Поддержка серверных страниц описывается, что если вы хотите обойти поведение service worker и избежать возвращения содержимого /index.html для всех запросов навигации, необходимо изменить логику работы service worker.

Все содержимое манифеста рабочего ресурса службы кэшируются

Как описывается выше в разделе Управление кэшированием ресурсов, файл service-worker-assets.js создается в процессе сборки и содержит список всех ресурсов, которые должна получать и кэшировать рабочая роль службы.

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

Реализуйте произвольную логику, ограничивающую получение и кэширование содержимого манифеста, внеся соответствующие изменения в функцию onInstall в файле service-worker.published.js.

Взаимодействие с технологиями проверки подлинности

Шаблон PWA можно использовать вместе с проверкой подлинности. Прогрессивные веб-приложения с поддержкой автономной работы также могут обеспечивать проверку подлинности при наличии у пользователя начального подключения к сети.

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

Если приложение, предназначенное для работы в сети и в автономном режиме, снова подключено к сети:

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

Чтобы создать автономное приложение PWA, взаимодействующее с проверкой подлинности:

  • замените AccountClaimsPrincipalFactory<TAccount> фабрикой, которая хранит последнего пользователя, выполнившего вход, и использует сохраненного пользователя, когда приложение находится в автономном режиме;
  • Постановка операций в очередь, пока приложение находится в офлайн-режиме, и их применение при возврате приложения к онлайн-режиму.
  • во время выхода очистите сохраненного пользователя.

Описанные выше подходы демонстрируются в примере приложения CarChecker. Ознакомьтесь со следующими частями приложения:

  • OfflineAccountClaimsPrincipalFactory (Client/Data/OfflineAccountClaimsPrincipalFactory.cs)
  • LocalVehiclesStore (Client/Data/LocalVehiclesStore.cs)
  • Компонент LoginStatus (Client/Shared/LoginStatus.razor)

Дополнительные ресурсы

Согласование между источниками на стороне SignalR клиента для проверки подлинности