pwa应用进阶2-动态加载manifest.json文件 | 南锋

南锋

南奔万里空,脱死锋镝余

pwa应用进阶2-动态加载manifest.json文件

pwa应用进阶-区分AB面-添加安装按钮而且区分不同的系统和浏览器的各种情况继续优化,主要是让manifest.json文件动态加载。
主要用途如下:

  • 动态切换PWA的清单文件,例如根据不同的语言或者主题加载不同的manifest
  • 更新资源路径,例如在不同环境下切换不同的manifest文件。

步骤及说明

  1. 修改index.htmlmanifest的引用
    将之前的

    1
    <link rel="manifest" href="/manifest.json">

    改为

    1
    <link rel="manifest" id="my-manifest">
  2. 向服务器动态的请求manifest.json文件,代码如下:

    1
    let manifestURL = 'https://www.lengmo714/manifest?p='+p;

    其中,这里的链接为你自己服务器的链接,p为参数,可以自己设定。

  3. 修改index.html<ilnk>标签的href属性,代码如下:

    1
    document.querySelector('#my-manifest').setAttribute('href', manifestURL);

    示例代码:
    我这里是想要将url地址中动态生成的参数带入我的应用中

    1
    2
    3
    4
    5
    6
    let url = "https://lengmo714.top"+window.location.search;
    let p = {start_url:url,'i1':'/icon-192x192.png','i2':'/icon-512x512.png'};
    p = JSON.stringify(p);
    p = encodeURIComponent(p);
    let manifestURL = 'https://www.lengmo714/manifest?p='+p;
    document.querySelector('#my-manifest').setAttribute('href', manifestURL);

    这里我将manifest.json中的start_url和两个icon传给服务器,服务器返回给我一个manifest.json文件,然后我再动态的加载这个文件。

服务器代码

我这里是使用的go语言,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package main

import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)

// Manifest 结构体
type Manifest struct {
Name string `json:"name"`
ShortName string `json:"short_name"`
StartURL string `json:"start_url"`
Display string `json:"display"`
ThemeColor string `json:"theme_color"`
BackgroundColor string `json:"background_color"`
Icons []Icon `json:"icons"`
}

// Icon 结构体
type Icon struct {
Src string `json:"src"`
Sizes string `json:"sizes"`
Type string `json:"type"`
}

func manifestHandler(w http.ResponseWriter, r *http.Request) {
// 获取 URL 参数 p
p := r.URL.Query().Get("p")
if p == "" {
http.Error(w, `{"error": "Missing parameter 'p'"}`, http.StatusBadRequest)
return
}

// 解析 URL 编码的 JSON 字符串
decodedP, err := url.QueryUnescape(p)
if err != nil {
http.Error(w, `{"error": "Failed to decode parameter 'p'"}`, http.StatusBadRequest)
return
}

// 解析 JSON 数据
var data map[string]string
err = json.Unmarshal([]byte(decodedP), &data)
if err != nil {
http.Error(w, `{"error": "Invalid JSON format"}`, http.StatusInternalServerError)
return
}

// 生成 manifest.json
manifest := Manifest{
Name: data["name"],
ShortName: data["name"],
StartURL: data["start_url"],
Display: "standalone",
ThemeColor: "#ffffff",
BackgroundColor: "#000000",
Icons: []Icon{
{Src: data["i1"], Sizes: "192x192", Type: "image/png"},
{Src: data["i2"], Sizes: "512x512", Type: "image/png"},
},
}

// 设置 HTTP 头
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)

// 返回 JSON 响应
json.NewEncoder(w).Encode(manifest)
}

func main() {
http.HandleFunc("/manifest", manifestHandler)
port := 8080
fmt.Printf("Server running at http://localhost:%d\n", port)
http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
}

自己在服务器另起一个go的服务器即可。

+