受欢迎的博客标签

How to Create Progressive Web Applications with ASP.NET Core Blazor WebAssembly step by step?

Published

.Net 8.x

https://learn.microsoft.com/zh-cn/aspnet/core/blazor/progressive-web-app?view=aspnetcore-8.0&tabs=visual-studio

 

.Net 5.x

Step 1:Create  a Web Applications with ASP.NET Core Blazor WebAssembly( Progressive Web Applications is  not checked)

git github.com

 

Step 2:Create a Progressive Web Applications with ASP.NET Core Blazor WebAssembly(Progressive Web Applications checked),then overwrite old project.

git to github.com

 

Step 3:Some of codes have changed

https://github.com/iaspnetcore/Nop.BlazorWebassembly.PWA/commit/7a4fb09d78171f9d323b073b374cd956621c907e

Nop.BlazorWebassembly.PWA.csproj

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
   + <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.5" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.5" PrivateAssets="all" />
    <PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
  </ItemGroup>

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

</Project>

files changed

+wwwroot/icon-512.png
+wwwroot/manifest.json
+wwwroot/service-worker.js
+wwwroot/service-worker.published.js

wwwroot/index.html changed

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>Nop.BlazorWebassembly.PWA</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />
    <link href="Nop.BlazorWebassembly.PWA.styles.css" rel="stylesheet" />
  +  <link href="manifest.json" rel="manifest" />
  +  <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
</head>

<body>
    <div id="app">Loading...</div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>
   + <script>navigator.serviceWorker.register('service-worker.js');</script>
</body>

</html>

 

\Nop.BlazorWebassembly.PWA\wwwroot\manifest.json

This JSON file is the root heart of the PWA. This is an industrial standard life. In this file we will declare and setup the PWA.

manifest.json是个清单文件,当程序被安装到设备上的时候会读取里面的信息,名称是什么,图标是什么,什么语言等等。

{
  "name": "Nop.BlazorWebassembly.PWA",
  "short_name": "Nop.BlazorWebassembly.PWA",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#03173d",
  "icons": [
    {
      "src": "icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ]
}

 the JSON nodes in the manifest.json

name – Display name of the Application
short_name – The short name of our application
start_url – Denotes the Root Directory
background_color – We can set the background color of the application
theme_color – Sets theme color of the application
icons – The desktop icon of our application

 

Step 1:Creating PWA with Blazor WebAssembly and Enable the Progressive Web Application Option

Choose Blazor WebAssembly and Enable the Progressive Web Application Option。

In order to create PWA, we need to choose Blazor WebAssembly App, since PWA always does not have a server. We also need to enable the Progressive Web Application as shown below. By enabling, it will turn our Blazor WebAssembly Application into a Progressive Web Application.

Step 2:

We can see four new files as icon-512.png, manifest.json, service-worker.js, and service-worker.published.js
 
icon-512.png
The Desktop Icon for our application, which is the default blazor icon

 

service-worker.js file contains below details.  

Service Worker 一个用于在 web 浏览器后台运行并拦截 HTTP 请求的脚本的 W3C 标准 API.

service-worker用来跑一些后台任务。它跟浏览器主进程是隔离的,也就是说跟原来的JavaScript运行时是分开,当然了它不会阻塞页面。我们可以用它来完成一些功能,比如对所有的fetch/xhr请求进行过滤,哪些请求走缓存,哪些不走缓存;比如在后台偷偷给你拉一些数据缓存起来。

// Caution! Be sure you understand the caveats before publishing an application with
// offline support. See https://aka.ms/blazor-offline-considerations

self.importScripts('./service-worker-assets.js');
self.addEventListener('install', event => event.waitUntil(onInstall(event)));
self.addEventListener('activate', event => event.waitUntil(onActivate(event)));
self.addEventListener('fetch', event => event.respondWith(onFetch(event)));

const cacheNamePrefix = 'offline-cache-';
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];

async function onInstall(event) {
    console.info('Service worker: Install');

    // Fetch and cache all matching items from the assets manifest
    const assetsRequests = self.assetsManifest.assets
        .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
        .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
        .map(asset => new Request(asset.url, { integrity: asset.hash }));
    await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}

async function onActivate(event) {
    console.info('Service worker: Activate');

    // Delete unused caches
    const cacheKeys = await caches.keys();
    await Promise.all(cacheKeys
        .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName)
        .map(key => caches.delete(key)));
}

async function onFetch(event) {
    let cachedResponse = null;
    if (event.request.method === 'GET') {
        // For all navigation requests, try to serve index.html from cache
        // If you need some URLs to be server-rendered, edit the following check to exclude those URLs
        const shouldServeIndexHtml = event.request.mode === 'navigate';

        const request = shouldServeIndexHtml ? 'index.html' : event.request;
        const cache = await caches.open(cacheName);
        cachedResponse = await cache.match(request);
    }

    return cachedResponse || fetch(event.request);
}

service-worker.js file contains below details.

修改service-worker
离线的原理也很简单,就是请求的数据都缓存起来,一般是缓存Get请求,比如各种页面图片等。

// In development, always fetch from the network and do not enable offline support.
// This is because caching would make development more difficult (changes would not
// be reflected on the first load after each change).

self.addEventListener('fetch', event => event.respondWith(onFetch(event)));
self.addEventListener('install', event => event.waitUntil(onInstall(event)));

async function onInstall(event) {
    console.info('Service worker: Install');
}


async function onFetch(event) {
    let cachedResponse = null;
    const cache = await caches.open('blazor_pwa');
    if (event.request.method === 'GET') {
        const request = event.request;
        cachedResponse = await caches.match(request);
        if (cachedResponse) {
            return cachedResponse;
        }
        var resp = await fetch(event.request)
        cache.put(event.request, resp.clone());
        return resp;
    }

    return fetch(event.request);
}

 

Sending push notifications

Like any other PWA, a Blazor WebAssembly PWA can receive push notifications from a backend server. The server can send push notifications at any time, even when the user isn't actively using the app.

https://docs.microsoft.com/en-us/aspnet/core/blazor/progressive-web-app?view=aspnetcore-5.0&tabs=visual-studio#push-notifications

https://github.com/dotnet-presentations/blazor-workshop/blob/master/docs/09-progressive-web-app.md#sending-push-notifications

 

Useful links

Build Progressive Web Applications With Blazor WebAssembly

 

2.使用Blazor WebAssembly创建PWA应用图解

安装到桌面

安装到华为手机和iPhone

https://zhuanlan.zhihu.com/p/353329118