MiniApp 打包

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2025/WD-miniapp-packaging-20250128/
最新发布版本:
https://www.w3.org/TR/miniapp-packaging/
最新编辑草案:
https://w3c.github.io/miniapp-packaging/
历史:
https://www.w3.org/standards/history/miniapp-packaging/
提交历史
编辑:
Martin Alvarez-Espinar华为
Qing An阿里巴巴
Tengyuan Zhang百度公司
Yongjing Zhang华为
Dan Zhou百度公司
前任编辑:
Shouren Lan华为
Zhiqiang Yu华为
Qian Liu百度公司
Shuo Wang百度公司
反馈:
GitHub w3c/miniapp-packaging拉取请求新建议题未解决议题

摘要

本规范定义了 MiniApp 包的语义和一致性要求,以及 保存 MiniApp 资源的单文件容器的结构,包括清单文件、 静态页面模板、样式表、JavaScript 文档、媒体文件和其他资源。 MiniApp 包的实例用于 MiniApp 的分发,以及在 运行时环境(MiniApp 用户代理)中执行。

本文档状态

本节描述本文档在发布时的状态。当前 W3C 出版物列表以及本技术报告的最新修订版本可在 W3C 技术 报告索引中找到,网址为 https://www.w3.org/TR/。

本文档由 MiniApps 工作 组作为 工作草案发布,使用 推荐标准轨道

作为工作草案发布并不 意味着获得 W3C 及其成员的认可。

这是一份草案文档,可能随时被其他文档更新、替换或废弃。 不应将本文档作为正在进行的工作之外的内容引用。

本文档由一个按照 W3C 专利 政策运作的小组编制。 W3C 维护一份 与该小组交付成果相关的任何专利 披露的公开列表; 该页面还包含 披露专利的说明。实际知悉某项专利且认为该专利包含 必要权利要求 的个人,必须按照 W3C 专利政策第 6 节 披露相关信息。

本文档受 2023 年 11 月 03 日 W3C 流程文档管辖。

1. 引言

1.1 概述

MiniApp 是一种轻量级软件应用的概念,可以通过任何数字方式 分发,并通过 Web 访问。MiniApp 由具体的 文件结构定义,其所有资源都打包在单个文件中,该文件表示整个 MiniApp 包,可由 MiniApp 用户代理处理和执行。

MiniApp 包包含一个目录结构,用于保存 MiniApp 的特定资源,这些资源定义渲染、操作以及与 最终用户的交互——包括静态页面模板、样式表、JavaScript 文档、媒体文件和其他 资源——以及清单。MiniApp 清单位于包的中央目录中,用于描述 MiniApp,包括 有关页面路由、样式以及 MiniApp 的其他操作和渲染细节的信息, 以及面向人类的描述性信息。

安全性考量中所定义,MiniApp MAY 支持数字签名验证,以保证 包及其内容在包交付过程中的完整性。

MiniApp 运行时环境(MiniApp 用户代理)通过本文档中定义的标准 MiniApp 包格式和特定的 MIME 媒体类型来识别 MiniApp 包 文件。在获取 MiniApp ZIP 容器之后,MiniApp 用户代理按照解引用和处理算法,将静态页面模板、样式表、 JavaScript 文件和其他资源加载到缓存中。这些 MiniApp 资源会在缓存中保持可用,直到下一次 更新,从而避免不必要的网络获取。

就启动模式而言,MiniApp 可以在离线时正常启动。MiniApp 用户代理从包缓存路径中定位指定的 起始页,并按照 MiniApp 清单文件中给出的描述启动 MiniApp。

1.2 术语

以下术语专用于 MiniApp。

数字签名
一种密码机制和散列技术,用于证明资源的真实性。数字签名可以证明资源以及 MiniApp 包的来源、时间、 身份和状态。
MiniApp
一种轻量级软件应用,可以通过任何数字方式分发,并通过 Web 访问。MiniApp 由具体的文件结构定义,在单个文件 MiniApp ZIP 容器内分发,该容器表示整个 MiniApp 包,可由 MiniApp 用户代理处理和执行。
MiniApp 包
一种逻辑文档实体,由打包在 MiniApp ZIP 容器中的一组资源组成。
MiniApp 资源
作为 MiniApp 视图或逻辑的一部分的逻辑文档。资源以物理形式包含在 MiniApp 包中。
MiniApp 页面
MiniApp 用户代理中显示的 一组信息,位于特定 MiniApp 的作用域之下。
MiniApp 用户代理
一种软件应用,用于获取、处理并渲染 MiniApp 包, 使 MiniApp 能够执行并与最终用户交互。
MiniApp ZIP 容器
基于 ZIP 的 MiniApp 打包和分发格式,如MiniApp ZIP 容器一节所定义。
MiniApp 小部件
一种特殊类型的 MiniApp 页面,在宿主环境中以独立方式显示, 例如助手和设备搜索页面,用于在特定场景中连接 MiniApp 服务。
MiniApp 起始页
MiniApp 的入口点。它是在应用启动时由 MiniApp 用户代理加载和渲染的资源。

1.3 一致性

除标记为非规范性的章节外,本规范中的所有编写指南、图示、示例和说明 均为非规范性。本规范中的其他所有内容均为规范性。

本文档中的关键词 MAYMUSTMUST NOTSHALLSHOULDSHOULD NOT 应按照 BCP 14 [RFC2119] [RFC8174] 中的描述解释,但仅当它们以全大写形式出现时,如此处所示。

MiniApp Packaging 规范依赖 Infra Standard [INFRA] 来描述 算法。

2. 包一致性

一致的 MiniApp 包MUST 满足以下 条件:

2.1 目录和文件系统 结构

MiniApp 包具有带有一些限制以及 保留文件和子目录的文件结构。

以下示例展示了一个典型的文件系统结构:

示例 1:文件系统结构
/
    |___manifest.json
    |___app.js
    |___app.css
    |___pages/
    |       |___page1.js
    |       |___page1.html
    |       |___page1.css
    |___common/
    |       |___componentA.js
    |       |___componentA.html
    |       |___componentA.css
    |       |___example.png
    |___i18n/
            |___zh-Hans.json
            |___en-US.json

2.1.1 根目录

MiniApp 根目录MiniApp 包文件系统的基础目录。

根目录MiniApp 包中保存 若干保留文件,其中包括全局数据以及关于 MiniApp 生命周期管理的信息,包括:

manifest.json
MiniApp 清单是一个 JSON 文档,负责 MiniApp 的全局 配置。清单文件包含一组必需和可选 属性,用于指明 MiniApp 的设置,包括页面的路由和路径以及 MiniApp 的窗口配置(例如,导航栏样式、背景图像、 背景颜色、页面标题等),依照 MiniApp Manifest 规范 [MINIAPP-MANIFEST]。
app.css
此文件是应用的主样式表,开发者在其中定义 MiniApp 内页面的通用样式和 外观方面。它MAY 为空。
app.js
此脚本文档具有 MiniApp 的基本服务逻辑,并包含 MiniApp 生命周期 [MINIAPP-LIFECYCLE] 的基本 配置和控制,包括对启动、显示和隐藏 MiniApp 的 事件管理。

2.1.2 pages 目录

pages 目录包含一组用于显示和用户交互的文件, 属于 MiniApp 页面

MiniApp 页面由一组资源定义,其文件由唯一文件名 (例如 intro)和特定扩展名标识,该扩展名定义资源类型,例如应用的业务逻辑 (例如 intro.js)、结构和内容(例如 intro.html)以及 作用域样式表(例如 intro.css)。

开发者MAY 根据需要包含其他类型的资源。 此外,与页面相关的文件(以相同文件名标识)MAY 组织在每个页面的特定子目录中,或 直接存储在 pages 目录下。

示例 2:直接位于 pages 目录中的页面资源
/
    |___manifest.json
    |___app.js
    |___app.css
    |___pages/
            |___detail.js
            |___detail.html
            |___detail.css
            |___list.js
            |___list.html
            |___list.css
示例 3:组织在 子目录中的页面资源
/
    |___manifest.json
    |___app.js
    |___app.css
    |___pages/
            |___detail/
                    |___detail.js
                    |___detail.html
                    |___detail.css
            |___list
                    |___list.js
                    |___list.html
                    |___list.css
  • .html 资源定义 MiniApp 页面的结构和内容。基于 HTML,该类型文件的语法、 结构和其他要求在 HTML 资源一节中定义。
  • .css 资源定义 MiniApp 页面的样式表。该类型资源的语法、 结构和其他要求在 CSS 资源一节中定义。
  • .js 资源包含 MiniApp 页面的业务逻辑,包括应用运行所需的函数、数据和其他配置 方面。此类资源负责 MiniApp 页面的设置和生命周期管理,如 MiniApp Lifecycle 规范 [MINIAPP-LIFECYCLE] 中所定义。这些类型文件的语法和格式在 脚本资源一节中定义。

2.1.3 common 目录

可选的 common 目录包含资源,例如 可从 MiniApp 中的页面访问的组件、多媒体资源、文档和库。 此目录的内部结构是灵活的,因此这些公共资源MAY 可根据需要 组织在自定义子目录中,并使用不同的命名约定。

2.1.4 i18n 目录

可选的 i18n 目录根目录中的一个 子目录,其中包含 本地化资源,属于 MiniApp 包

i18n 目录包含多语言本地化资源,用于支持 MiniApp 内容的 国际化。此目录中每个 .json 文档的文件名遵循 [BCP47] 中定义的 Language-Tag 表示法,并表示该特定语言的具体 配置。

i18n 目录MAY 包含与 MiniApp 支持的语言或区域设置一样多的本地化资源。这些文件的格式在 本地化资源一节中定义。

2.1.5 文件名和路径名

MiniApp 包中的任何文件名和路径名 MUST 遵守以下限制,以适应操作系统的潜在 限制,并促进与大多数 平台和文件系统的互操作性,如 面向规范开发者的国际化最佳实践所指定。

  • 文件名和文件路径区分大小写。
  • 文件名和文件路径 MUST 使用 UTF-8 [Unicode] 编码。
  • 文件名SHOULD NOT 超过 255 字节长度。
  • 路径名SHOULD NOT 超过 65535 字节长度。
  • 文件名和路径名 MUST NOT 使用以下 [Unicode] 码点:
    • " [U+0022 QUOTATION MARK]
    • * [U+002A ASTERISK]
    • / [U+002F SOLIDUS]
    • : [U+003A COLON]
    • < [U+003C LESS-THAN SIGN]
    • > [U+003E GREATER-THAN SIGN]
    • \ [U+005C REVERSE SOLIDUS]
    • | [U+007C VERTICAL LINE]
    • U+007F DEL
    • U+E0001 LANGUAGE TAG
    • U+E007F CANCEL TAG
    • 以下范围内的码点:
      • C0 控制符 [U+0000...U+001F]
      • C1 控制符 [U+0080...U+009F]
      • 专用区 [U+E000...U+F8FF]
      • 特殊区 [U+FFF0...U+FFFF]
      • 补充专用区 [U+F0000...U+FFFFF]
      • 补充专用区 [U+100000...U+10FFFF]
    • . [U+002E FULL STOP]
    • 所有 Unicode 非字符码点,具体包括:
      • 基本多文种平面中的 32 个连续字符(U+FDD0 … U+FDEF)
      • 基本多文种平面的最后两个码点(U+FFFE 和 U+FFFF)
      • 补充平面末尾的最后两个码点(U+1FFFE、 U+1FFFF … U+EFFFE、U+EFFFF)

同一目录中的所有文件名 MUST 在经过 Unicode 规范等价归一化 [UAX15],然后经过完全大小写 折叠 [Unicode] 后保持唯一。(更多信息请参阅 Unicode 规范大小写 折叠归一化步骤 [CHARMOD-NORM]。)

说明:限制文件名长度
如果 MiniApp 供应商对路径名和文件名施加长度限制,重要的是避免 由于 UTF-8 等多字节 编码中字节和字符之间的差异而发生字符中间截断。更多信息请参阅 文本截断最佳 实践

2.2 MiniApp 资源

MiniApp 页面至少由一个 HTML 资源组成,并可选地由一个 CSS 资源和/或一个 脚本资源组成。 这些相关资源 MUST 具有相同的路径和文件名(只改变 文件扩展名),以通过唯一的页面路由 来标识 MiniApp 页面,该页面路由需要在 pages 成员中指定,属于 MiniApp 清单 [MINIAPP-MANIFEST]。

示例 4:对应页面路由 'pages/product/product' 的页面资源组织方式
/
    |___pages/
            |___product/
                    |___product.html
                    |___product.css
                    |___product.js

2.2.1 HTML 资源

HTML 资源是包含标记和信息的文档,用于定义 MiniApp 页面及其用户界面,包括结构、 视觉组件和交互元素。

HTML 资源MUST 满足 以下所有条件:

语法和内容
HTML 资源MUST 使用 [HTML] 中定义的 HTML 语法
文件名
HTML 资源SHOULD 具有 唯一文件名,用于标识单个 MiniApp 页面,并在存在时与页面的 对应 CSS 资源脚本 资源匹配。
文件扩展名
HTML 资源SHOULD 使用 文件扩展名 .html
编辑 说明
用于定义 MiniApp 内容文档的 HTML 配置文件。

2.2.2 CSS 资源

CSS 资源是描述 MiniApp 页面渲染和外观的样式表。CSS 资源可以是全局的, 影响 MiniApp 中的所有页面(即根 目录中的 app.css),也可以具有局部作用域,只影响 MiniApp 中的特定 页面

本规范支持 [CSS-SNAPSHOT] 中定义的 CSS 模块。

CSS 资源 MUST 满足以下所有条件:

语法和内容
CSS 资源MUST 遵循 [CSS-SNAPSHOT] 中所描述的 CSS 语法和定义。
文件名
影响 MiniApp 中所有页面的全局 CSS 资源MUST 命名为 app.css,并存储在根 目录中。
页面关联的局部 CSS 资源SHOULD 具有唯一文件名, 用于标识 MiniApp 页面,并在存在时与对应的 HTML 资源脚本 资源匹配。
文件扩展名
CSS 资源文件名SHOULD 使用文件扩展名 .css

2.2.3 脚本资源

脚本资源是包含脚本元素和 数据的文档,用于控制应用的业务逻辑和功能,增加交互性并 管理 MiniApp 的生命周期。存在一个全局脚本 资源(即根 目录中的 app.js),其中包含适用于 MiniApp 所有 页面的数据和函数,并包含用于控制 应用生命周期的特定逻辑。每个 MiniApp 页面MAY 具有 关联的特定脚本资源,其作用域限于具体 页面

脚本资源 MUST 满足以下所有条件:

语法和内容
脚本资源MUST 符合 ECMAScript 规范 [ECMA-262] 的要求。
全局脚本资源MUST 命名为 app.js,并存储在根 目录中。
页面关联的局部 脚本资源SHOULD 具有唯一文件名, 用于标识 MiniApp 页面,并在存在时与对应的 HTML 资源CSS 资源匹配。
文件扩展名
脚本资源文件名SHOULD 使用文件扩展名 .js

2.2.4 本地化资源

MiniApp 本地化资源MiniApp 包中的一种文档,作为 MiniApp 国际化机制的一部分,其中包含本地化内容。

多语言 MiniApp MAY 具有多个本地化资源,这些资源将在本地化过程中由用户代理使用,以根据系统区域设置或 用户的语言偏好渲染内容。这些资源包含带有键值对的 JSON 对象, 其中键值对包含可本地化术语或表达式的唯一标识符(键)以及 具体语言中的表示形式(值)。

示例 5:本地化资源
{
        "title": "Cool MiniApp",
        "about": "About this MiniApp",
        "intro-page": {
            "title" : "Introduction",
            "main" : "This is the body of the page"
        }
    }

本地化资源MUST 满足以下所有条件:

文件扩展名
本地化资源文件名SHOULD 使用文件扩展名 .json
格式
本地化资源MUST 是有效的 JSON 文档 [JSON]。
结构
本地化资源MUST 由键值对组成。每个键表示每个可本地化字符串 (值)的唯一标识符。

3. MiniApp ZIP 容器

3.1 引言

本节为非规范性。

MiniApp ZIP 容器是 MiniApp 的物理单文件表示形式, 可用于在不同场景中分发 MiniApp,包括:

MiniApp ZIP 容器在单个文件中包含构成 MiniApp 的全部资源,并符合 MiniApp 包结构。此格式支持 使用压缩机制。

3.2 ZIP 文件要求

MiniApp ZIP 容器使用 [ZIP] 中定义的 ZIP 格式,并具有一些特殊要求:

MiniApp ZIP 容器的结构如下:

[ZIP File Entries]
    [MiniApp Signing Block]    
    [ZIP Central Directory]
    [End of ZIP Central Directory]
标准 ZIP 包以及中间带有签名块的 MiniApp 包的结构
1 ZIP 包以及带有可选签名块的 MiniApp 包

MiniApp ZIP 容器的解析方式是先找到 ZIP 中央目录的起始位置(定位文件末尾的 ZIP End of Central Directory 记录, 然后从该记录读取中央目录的起始偏移量)。每个 MiniApp 签名块MAY 包含一个 签名块魔数块,如 数字签名要求中所规定, 用于标识数字签名的存在。一旦识别出 “magic numbers” 块,用户代理就能够处理数字签名,这些签名存储在 中央目录紧前面的签名块中,如2所示。

标准 ZIP 包以及中间带有签名块并引用包中不同块的 MiniApp 包的结构
2 使用相对偏移寻址引用不同块的 ZIP 和 MiniApp 包

MiniApp 供应商 MAY 根据其 需求采用数字签名方案。

编辑 说明:添加扩展名

MiniApp 文件 MAY 通过 .ma 文件扩展名标识,尽管并不要求 使用文件扩展名。

3.3 数字签名要求

MiniApp ZIP 容器MAY 包含零个、 一个或多个签名,以帮助检测软件受保护部分的任何更改, 从而保证 MiniApp 的完整性。

MiniApp 签名块是一组 字节,其中包含关于影响 MiniApp(部分或整体)的数字签名的特定信息 和元数据。签名块MiniApp ZIP 容器MUST 位于 ZIP 容器中央目录的紧前方,以便在存在时更容易定位 该块。

签名块魔数块是一个 16 字节序列, 具有唯一指纹,用于标识 MiniApp 包的数字签名机制,并存储在 MiniApp ZIP 容器的签名块中。

尽管本文档不推荐任何特定的数字签名机制(即散列 算法、加密方法等),但如果存在签名块,则其 MUST 满足以下条件:

签名块魔数
签名块MUST 包含签名块魔数,作为中央目录的前置块, 用于唯一标识所包含数字签名的类型。

4. 国际化

国际化,缩写为 i18n,是以确保产品能够容易适配来自任何文化、 地区或语言的用户的方式来设计和开发产品的过程。

本地化是为了满足目标语言或 文化要求而进行内容适配的过程。

MiniApp 使用一种基于放置在保留的 i18n 目录中的本地化文档的机制来实现内容本地化。 此机制允许作者放置本地化资源,这些资源按照 language-range [BCP47] 和 .json 扩展名命名。 也就是说,包含本地化资源的文档将使用语言标签 [BCP47] 标识,这些标签表示内容的区域设置。MiniApp 用户代理会将其区域设置所持有的语言范围 与适当的区域设置文件名进行匹配。

本地化资源的格式在 本地化资源一节中定义。

示例 6:i18n 目录中基于语言标签的文件名
/
    |___i18n/
    |     |___en-US.json
    |     |___fr-FR.json
    |     |___fr.json            
    |     |___ja-JP.json
    |     |___zh-Hans.json

5. MiniApp 包处理

用户代理MUST 遵循以下 算法,以解引用、解析并执行 MiniApp 包

处理 MiniApp 包,给定 URL miniapp_uri,执行 以下步骤:

  1. miniapp_zip_file 为使用 miniapp_uri 获取 MiniApp ZIP 容器的结果。
  2. 使用 miniapp_zip_file验证 MiniApp ZIP 容器
  3. miniapp_package 为解压 miniapp_zip_file 的结果。
  4. 如果 miniapp_package 是解压异常,则返回失败。
  5. 有序映射 manifest 为使用 miniapp_package处理 MiniApp 清单的结果。
  6. start_page 为使用 miniapp_urimanifest准备平台运行时的结果。
  7. 字符串 locale 为传入 manifest提取区域设置的结果。
  8. 启动 MiniApp,并传入 miniapp_packagemanifeststart_pagelocale

5.1 MiniApp ZIP 容器 获取

用户代理MAY 通过不同渠道获取 MiniApp ZIP 容器,包括通过网络获取 文件(即使用 HTTPs、WebSocket、FTP 或其他特定的基于 TCP/UDP 的协议), 也可以从文件系统获取或使用任何其他机制。

获取 MiniApp ZIP 容器,给定 URL miniapp_uri, 执行以下步骤。它们返回一个 MiniApp ZIP 容器

  1. resourceMiniApp ZIP 容器,作为获取 URL [FETCH] 并传入 miniapp_uri 的结果。
  2. supplied_mime_type 为使用 resource 应用所提供 MIME 类型检测算法 [MIMESNIFF] 的结果。
  3. 如果 supplied_mime_type 不等于 application/miniapp-pkg+zip,则返回失败。
  4. 返回 resource

5.2 MiniApp ZIP 容器 验证

用户代理MAY 通过验证数字 签名并应用密码机制,保证 MiniApp ZIP 容器及其内容的合法性 和完整性。

验证 MiniApp ZIP 容器,给定 MiniApp ZIP 容器 miniapp_zip_file,执行以下步骤:

  1. 如果用户代理具有对 miniapp_zip_file 执行数字签名 验证的能力,则:
    使用 miniapp_zip_file处理数字 签名

5.2.1 数字签名 处理

MiniApp ZIP 容器MAY 包含一个 签名块,其中包括一个或多个签名。 签名方案和密码机制取决于用户代理的具体实现。

签名方案由 魔数部分标识,该部分包含在 MiniApp ZIP 容器中,是一个 16 字节序列,位于 ZIP 包 中央目录的紧前方。

处理数字签名,给定 MiniApp ZIP 容器 miniapp_zip_file,执行以下步骤:

  1. magic_numbers字节序列
  2. eocd_pointer 为在 miniapp_zip_file 中定位字节序列 0x06054b50(按小端序读取)的结果,作为字节序列,该字节序列标记 中央目录的结束 [ZIP]。
  3. eocd_pointer 设置为 eocd_pointer + 0x00000010。
  4. cd_pointer 为读取 eocd_pointer 处 4 字节序列的结果。
  5. magic_numbers_pointereocd_pointer - 0x00000010。
  6. magic_numbers 设置为 magic_numbers_pointer 处的 16 字节块。
  7. 使用 magic_numbersminiapp_zip_file 处理数字签名。
说明:用法
MiniApp 用户代理根据其需求和要求实现特定的数字签名 处理算法。

5.3 MiniApp 清单处理

用户代理MUST 解析位于 MiniApp 清单中的 MiniApp 包,其中包含关于 MiniApp 的全局元数据。

处理 MiniApp 清单,给定 MiniApp 包 miniapp_package,执行以下步骤。它们返回有序映射

  1. 如果 manifest.json 文件不存在于包的根目录中,则返回失败。
  2. manifest_json 为传入 manifest.json从 字节解析 JSON的结果。
  3. 如果 manifest_json 是解析异常,或者 manifest_json 不是有序映射,则返回失败。
  4. manifest 为一个有序映射
  5. 处理 MiniApp 清单,传入 manifest_jsonmanifest
  6. 返回 manifest

5.4 平台运行时准备

用户代理SHOULD 准备同时包含逻辑层和视图层的运行时 环境。逻辑层负责应用的逻辑 和控制(即 app.jspage.js 文件)。视图 层负责视觉环境和渲染,包括页面资源文件,例如 组件模板和样式表。为了准备运行 MiniApp,用户代理MUST 使用 MiniApp 清单元数据指定的配置来设置环境。

用户代理MUST 按照以下 算法,将起始页标识并加载为 MiniApp 入口点。

准备平台运行时,给定 URL miniapp_uri有序映射 manifest,执行以下步骤。它们返回一个 MiniApp 起始页

  1. 如果 app.js 不存在于根 目录中,则返回失败。
  2. 如果 app.css 不存在于根 目录中,则返回失败。
  3. 验证平台兼容性,传入 miniapp_packagemanifest
  4. start_page确定起始页的结果,传入 miniapp_packageminiapp_urimanifest
  5. 返回 miniapp_uri

5.4.1 平台 兼容性验证

用户代理MUST 验证 MiniApp 与其兼容,并且能够在其 平台中正常运行。此验证使用 MiniApp 清单中指定的元数据执行,包括平台支持版本,以及 检查执行中所需的页面和资源。

验证平台兼容性,给定 MiniApp 包 miniapp_package有序映射 manifest,执行以下步骤:

  1. platform_required 设置为 manifest["platform_version"]。
  2. 如果 platform_required用户代理配置不兼容,则返回失败。
  3. manifest["pages"] 这个列表中的每个 page执行
    1. 如果 page 不存在于 miniapp_package 中,则返回失败。
  4. 如果 manifest["widgets"] 存在,则:
    manifest["widgets"] 这个列表中的每个 widget_path执行
    1. 如果 widget_path 不存在于 miniapp_package 中,则返回失败。

5.4.2 起始页识别

默认情况下,用户代理MUST 在 MiniApp 启动时, 将 起始页作为入口点加载,该起始页在 MiniApp 清单中指明。若 MiniApp URI 中指定了有效的 页面,则默认的 起始页MUST 被覆盖,如以下 算法所规定。

确定起始页,给定 MiniApp 包 miniapp_packageURL miniapp_uri有序映射 manifest,执行以下步骤。它们返回一个 URL

  1. start_page 为传入 miniapp_uri从 URI 提取起始页的结果。
  2. 如果 start_page 未设置,或者 start_page 等于 null,或者 start_page 不存在于 miniapp_package 中,则:
    start_page 设置为传入 manifest从 清单提取起始页的结果。
  3. 返回 start_page
5.4.2.1 从 URI 提取起始页

MiniApp URI MAY 包含关于起始页的信息,该信息被指定为 URI 的 URL-path-segment string

从 URI 提取起始页,给定 URL miniapp_uri,执行以下步骤。它们返回一个 URL

  1. start_pageURL-path-segment string, 这是对 miniapp_uri 执行解析所得的结果。
  2. 如果 start_page 为失败,则返回 null。
  3. 返回 start_page
5.4.2.2 从清单提取起始页

MiniApp Manifest 的 pages 成员 [MINIAPP-MANIFEST] 中所述, MiniApp 的起始页pages 列表的第一项中指定。

从清单提取起始页,给定 有序映射 manifest,执行以下步骤。它们返回一个 字符串

  1. start_page_id 为空字符串
  2. 列表 pagesmanifest["pages"]。
  3. 返回 pages[0]。

5.4.3 提取区域设置

提取区域设置,给定 有序映射 manifest,执行以下步骤。它们返回一个 字符串

  1. 字符串 locale用户代理的 默认区域设置。
  2. 如果 manifest["lang"] 存在,并且如果 manifest["lang"] 受用户代理支持,则:
    locale 设置为 manifest["lang"]。
  3. 返回 locale

6. 可访问性考量

本节为非规范性。

本规范从逻辑和物理角度定义 MiniApp,详细说明其内部文件结构,以及不同资源如何打包在单个 文件中。此外,本文档还包含 MiniApp 用户代理用于获取和处理 MiniApp 容器的算法。

MiniApp Packaging 规范要求用户代理处理 MiniApp 容器及其内容,以基于内部 资源(即 HTML、样式表、脚本等)和配置(即清单、 app.ux)生成用户界面和具体行为。在包获取和处理之后,建议用户代理在每种可能场景中提供可感知且 可操作的用户界面和渲染内容,允许使用样式表根据用户需求调整外观, 并提供配置和控制显示选项以及窗口和视口方向的可能性,正如 manifest.json 的某些成员所要求的(MiniApp Manifest)。

虽然本文档未作规定,但建议用户代理保证用户交互中的可访问性方面,例如提供完整的键盘访问, 或支持替代输入设备(如果可行),并允许用户存储偏好设置以改善用户体验。MiniApp 用户代理和平台应提供用于渲染应用并与之交互的机制, 促进辅助技术的集成,并遵守适用的规范和约定,尤其是 用户代理可访问性指南(UAAG)2.0

7. 安全性考量

本规范定义了一种通过具体配置打包、分发和加载 MiniApp 的机制,该配置指定应用的入口点和不同路由 (即清单的 pages 成员)。用户代理SHOULD 通过限制要加载的资源类型, 并实现默认阻止访问强大特性的沙盒环境, 来缓解初始化和加载阶段的潜在漏洞。

7.1 资源和服务

MiniApp 用户代理容易受到 XSS 攻击,具体而言,是在获取和处理图像、数据源和脚本等外部 资源时受到攻击。因此,用户代理SHOULD 检查并限制潜在攻击向量,并通过 实现内容安全策略(CSP)来控制 MiniApp 可以获取或执行的 资源,从而缓解风险。

MiniApp 包MAY 包含任何类型的资源, 包括恶意脚本。因此,MiniApp 用户代理MUST 严格限制要处理的资源,通过丢弃未在清单中声明且未从组件正确绑定的资源, 将攻击面降至最低。因此,用户代理MUST 检查清单中指定资源 (即图像和组件页面)以及容器内包含的补充文件(即媒体文件、脚本、样式表等)的可用性, 并丢弃容器中的其余元素。此外,用户代理SHOULD 考虑实现允许使用第三方资源的 API 所带来的具体风险。

本文档不要求公开任何特定信息。然而,MiniApp 包包含可能描述目标用户代理及必要运行环境某些特征的 特性,包括操作系统版本和底层硬件能力(例如,可用传感器、设备类型以及 显示类型)。这些在 MiniApp 清单中指定的平台要求MAY 会在清单处理阶段中止 MiniApp 初始化的执行, 从而暴露与应用要求之间的一些不一致。尽管如此,用户代理SHOULD 避免公开 暴露此类信息,以减少攻击面。

MiniApp Packaging 未指定任何用于访问和暴露底层平台信息的具体机制。 然而,MiniApp 用户代理MAY 实现用于访问此类信息(例如,平台版本、 操作系统和可用传感器)的服务,以及用于与硬件和操作系统通信的 API。因此, 用户代理SHOULD 在支持这些敏感服务时 考虑潜在风险,并默认实现充分的缓解机制,以保证强大特性不会在没有有意义的用户 同意的情况下被激活。

7.2 包完整性和 可信度

为确保 MiniApp 分发阶段中的完整性和可信度,MiniApp 包SHOULD 由一个或多个 数字签名保护。这些签名以及受信任机构颁发的证书, 可以帮助第三方验证 MiniApp 作者(例如 MiniApp 开发者)以及参与软件开发或分发的其他实体 (例如作为 MiniApp 分发者的应用商店)的身份。

MiniApp 中通常包含数字签名的场景包括但不限于:

本规范不推荐任何特定的数字签名机制、密码技术或算法。 MiniApp 供应商MAY 根据其用例实现数字 签名机制。实现时,3.3 数字签名要求SHALL 被遵循。

一些技术和加密方法在B. 签名方案中介绍。

8. 隐私考量

MiniApp MAY 处理可在用户代理沙盒环境中持久化并保留, 以供后续应用执行使用的个人身份信息。用户代理MUST 保护该信息, 仅允许同一应用的实例访问数据,并避免公开暴露。因此, MiniApp 用户代理SHOULD 透明地 告知最终用户正在收集的数据类型以及收集目的。

最终用户MUST 决定是否移除用户代理针对任何 MiniApp 实例存储的信息。 用户代理SHOULD 将 存储的数据视为潜在敏感数据,确保删除数据时从底层存储中充分移除。 此外,用户代理SHOULD 实现机制,以最大限度降低敏感信息泄露风险并保护用户隐私, 例如在长时间不活动后自动移除存储的数据。在任何情况下,用户代理SHOULD 透明地告知用户所实现的具体隐私政策。

会话在应用被启动时开始,并在其从系统中卸载时终止,如 [MINIAPP-LIFECYCLE] 中所定义。虽然本规范未描述任何跨会话数据持久化机制, 但 MiniApp MAY 在用户设备上存储可在后续会话中检索的数据。 这种场景引入了在用户不知情或无法控制的情况下跟踪用户的风险。因此,MiniApp 用户代理MUST 实现保护措施,以确保客户端存储机制不能被滥用于在用户无法控制的情况下跟踪用户, 例如隔离 MiniApp 运行环境。这种隔离将为每个 MiniApp 提供专属存储空间,并通过清单的 app_id 成员进行唯一标识,限制其他 MiniApp 对数据的访问。

用户代理MAY 提供在系统上安装应用的可能性 (例如通过主屏幕快捷方式、桌面图标等)。此过程SHOULD 是透明且可逆的。 如果最终用户想要卸载应用,用户代理MUST 确保所有相关数据 都已从底层存储中充分移除。

本规范不推荐任何用于保护MiniApp 包机密性的加密机制。 然而,它并不排除为特定目的实现某些加密机制。

A. 致谢

本节为非规范性。

编辑说明
列出所有贡献者和 W3C 团队联系人

B. 签名方案

本节为非规范性。

每个用户代理MAY 根据其需求支持自己的数字 签名方案。本节包含一些数字签名实现示例,如4所示。它们可用于特定场景,例如开发者验证以及 MiniApp 在分发期间的完整性。

MiniApp 包中具有不同签名方案的签名块示例
4 MiniApp 包中包含的不同签名方法示例

B.1 RPK 签名方案

作为 MiniApp 的一种实现,快应用使用一种 所谓 RPK(Runnable Package)签名方案,它类似于 APK 签名方案 v2 [APK-SIGNATURE-V2],用于验证 MiniApp 包的作者身份。此签名方案会将 MiniApp 包中的每个字节纳入签名生成。生成的签名块 按照数字签名要求创建并插入包文件中。

签名块包含带有签名和签名者身份信息的 ID-value 对。

说明

RPK 签名块中的所有数据值均以 小端格式表示,并且所有带长度前缀的字段都使用 uint32 表示长度。

说明使用以下基本数据类型:

uint64
小端格式的 64 位(8 字节)无符号整数
uint32
小端格式的 32 位(4 字节)无符号整数

B.1.1 签名块格式

RPK 签名块的格式如下:

  • block size,以字节为单位,不包括此字段(uint64)
  • ID-value 对序列(其中签名被定义):
    • ID-value 对的size(uint64)
    • ID(uint32)
    • value(ID-value 对大小 - 4 字节)
  • 以字节为单位的block size(与第一个字段相同)(uint64)
  • magic numbersRPK Sig Block 42”(16 字节)

解释该块时会忽略具有未知 ID 的 ID-value 对。

"block size" 值用于定位整个 ZIP 文件中签名块的起始位置。

B.1.1.1 签名

签名以具有特定标识符的 ID-value 对形式存储,这些标识符表示签名类型。 RPK 包支持的签名及其关联 ID 在以下子条款中说明。

编辑 说明:package-splitting

在某些情况下,MiniApp 包会被拆分为多个子包(例如由应用商店等 分发平台拆分),以便用户代理以渐进方式下载和执行,从而改善用户体验。在这种情况下, 需要额外的签名类型(因此也需要 ID),以确保每个子包以及整体的完整性。 细节有待进一步研究。

B.1.1.1.1 开发者 签名

签名块中 ID 0x01000101 下的 ID-value 对表示整个文件 MiniApp 包签名的数据。

ID 对的值包含所有签名块,其长度可变,结构如下:

  • ID: 0x01000101(uint32)
  • value:
    • 签名者块的size,不包括此字段(uint32)
    • signer blocks 序列:
      • 签名者块的size,不包括此字段(uint32)
      • signed data:
        • 摘要的size,不包括此字段(uint32)
        • digests 序列:
          • 摘要块的size,不包括此 字段(uint32)
          • signature algorithm ID(uint32)
          • 摘要内容的size,不包括此 字段(uint32)
          • digest 内容(可变长度)
        • size of certificates,不包括此字段 (uint32)
        • certificates 序列:
          • 证书的size,不包括此 字段(uint32)
          • X.509 certificate [rfc2528] 以 ASN.1 DER 形式 [X690] 表示(可变长度)
        • 附加属性的size,不包括此 字段(uint32)
        • additional attributes
      • 签名的size,不包括此字段(uint32)
      • signatures 序列:
        • 签名的size,不包括此字段 (uint32)
        • signature algorithm ID(uint32)
        • 签名内容的size,不包括此字段 (uint32)
        • signature content(可变长度)
      • 公钥的size,不包括此字段(uint32)
      • public keyASN.1 DER [X690] 形式表示(可变长度)
B.1.1.1.2 分发者 签名

分发者的签名在分发过程中保持应用的完整性,保证该包由受信任的分发者验证, 并且来自分发者的权限控制策略(以 配置文件的形式) 会在包上强制执行。

在分发者签名过程中,分发者或开发者会添加一个配置文件,并使用分发者的私钥对签名进行签署。

配置文件存储在签名块中 ID 0x02000201 下的 ID-value 对中。

ID 对的值包含其所有签名块,其长度可变,结构如下:

  • ID: 0x02000201(uint32)
  • value:
    • 签名者块的size,不包括此字段(uint32)
    • signer block:
      • 配置文件size,不包括此字段(uint32)
      • provisioning profile。配置文件 ID-value 对序列, 按照配置文件 ID
        • ID-value 对的size,不包括此字段 (uint32)
        • ID(uint32)
        • value(可变长度)
      • 签名的size,不包括此字段(uint32)
      • signature algorithm ID,根据签名算法 ID的值 (uint32)
      • 签名内容的size,不包括此字段 (uint32)
      • signature content(可变长度)
B.1.1.1.2.1 签名 算法 ID
  • 0x0101 RSASSA-PSS,使用 SHA2-256 摘要、SHA2-256 MGF1、32 字节 salt,trailer: 0xbc
  • 0x0102 RSASSA-PSS,使用 SHA2-512 摘要、SHA2-512 MGF1、64 字节 salt,trailer: 0xbc
  • 0x0103 RSASSA-PKCS1-v1_5,使用 SHA2-256 摘要。用于需要确定性签名的 构建系统。
  • 0x0104 RSASSA-PKCS1-v1_5,使用 SHA2-512 摘要。用于需要确定性签名的 构建系统。
  • 0x0201 ECDSA,使用 SHA2-256 摘要
  • 0x0202 ECDSA,使用 SHA2-512 摘要
  • 0x0301 DSA,使用 SHA2-256 摘要
B.1.1.1.2.2 支持的密钥 大小和 EC 密码学:
  • RSA: 1024, 2048, 4096, 8192, 16384
  • EC: NIST P-256, P-384, P-521
  • DSA: 1024, 2048, 3072
B.1.1.1.2.3 配置文件 ID
  • 0x01 证书摘要
    • 证书摘要块的size,不包括此字段 (uint32)
    • signature algorithm ID,根据签名算法 ID的值(uint32)
    • 证书摘要数据的size,不包括此字段 (uint32)
    • certificate digest data(可变长度)
  • 0x02 证书
    • 证书的size,不包括此字段(uint32)
    • certificate dataASN.1 DER [X690] 形式表示(可变长度)
  • 0x03 用途:
    • app store,值:0x01
    • debug,值:0x02
    • enterprise,值:0x03
  • 0x04 清单
    • 清单的size,不包括此字段(uint32)
    • manifest 采用 UTF-8 [UNICODE](可变长度)
  • 0x05 设备 ID
    • 设备 ID 的size,不包括此字段(uint32)
    • Device IDs 序列:
      • 设备 ID 的size,不包括此字段(uint32)
      • Device ID,以 MD5 格式表示 [rfc1321] (可变长度)

B.2 PKCS#7 签名方案

此签名方案基于 PKCS #7 加密消息语法 [rfc2315]。它MAY 覆盖RPK 签名方案中描述的不同打包签名阶段,包括开发者签名和 分发者签名。

此签名方案在第一阶段(开发者签名阶段)包含 MiniApp 的配置文件 和开发者签名。在第二阶段(分发者签名阶段),分发者MAY 用自己的签名替换开发者的 签名。与RPK 签名方案类似, 此方法会生成一个签名块,并按照数字签名要求将其包含到包文件中。

PKCS#7 签名块被定义为一种数据容器,包含带有数字签名的块,以及 使用 PKCS #7 语法加密的数据,其中包含签名和签名者身份。

说明使用以下基本数据类型:

uint64
64 位(8 字节)无符号整数
uint32
32 位(4 字节)无符号整数
uint16
16 位(2 字节)无符号整数

B.2.1 签名块格式

PKCS#7 签名块的格式如下:

  • Signing block head
    • type 用于指示类型,根据签名块类型(1 字节)
    • tag 用于指示子类型,根据签名块类型(1 字节)
    • length(uint16)
    • offset(uint32)
  • Signature Block head:
    • reserved(4 字节)
    • number of blocks(uint32)
    • size(uint32)
    • version(4 字节)
    • magic numbersMIX Sig Block 42”(16 字节)
  • Data
  • PKCS #7 中的 Signature Block data
    • PKCS #7 内容类型设为 SignedData
      • version:语法版本号
      • digest algorithms:消息摘要算法标识符集合
      • 被签名的内容:
        • version(uint32)
        • size(uint16)
        • number of blocks(uint16)
        • Content Hash:
          • type(uint8)
          • tag(uint8)
          • algorithm ID(uint8)
          • length(uint32)
          • hash(可变长度)
      • certificates:一组 PKCS #6 扩展证书和 X.509 证书
      • crls:一组证书吊销列表
      • signerInfos:每个签名者信息的集合
    • Signer
  • Hw sign head:
    • number of blocks(uint32)
    • size(uint32)
    • version(4 字节)
    • magic numbersMIX Sig Block 42”(16 字节)
B.2.1.1 签名块类型

Block Head 的类型由其属性 type 标识。此属性MUST 采用两个不同的值:

如果 type 的值设置为 0(文件签名块),则头部MUST 使用其Block Head 中的属性 tag 指定一个更窄的子类型。此子类型的值为:

  • 0: 默认
  • 1: HASH(整文件哈希)
  • 0x80: 1M_HASH_ROOT(1M 块哈希树,根哈希)
  • 0x81: 512K_HASH_ROOT(512K 块哈希树,根哈希)
  • 0x82: 256K_HASH_ROOT(256K 块哈希树,根哈希)
  • 0x83: 128K_HASH_ROOT(128K 块哈希树,根哈希)
  • 0x84: 64K_HASH_ROOT(64K 块哈希树,根哈希)
  • 0x85: 32K_HASH_ROOT(32K 块哈希树,根哈希)
  • 0x86: 16K_HASH_ROOT(16K 块哈希树,根哈希)
  • 0x87: 8K_HASH_ROOT(8K 块哈希树,根哈希)
  • 0x88: 4K_HASH_ROOT(4K 块哈希树,根哈希)
  • 0x90: 1M_HASH_BLOCK(1M 块哈希树)
  • 0x91: 512K_HASH_BLOCK(512K 块哈希树)
  • 0x92: 256K_HASH_BLOCK(256K 块哈希树)
  • 0x93: 128K_HASH_BLOCK(128K 块哈希树)
  • 0x94: 64K_HASH_BLOCK(64K 块哈希树)
  • 0x95: 32K_HASH_BLOCK(32K 块哈希树)
  • 0x96: 16K_HASH_BLOCK(16K 块哈希树)
  • 0x97: 8K_HASH_BLOCK(8K 块哈希树)
  • 0x98: 4K_HASH_BLOCK(4K 块哈希树)

C. 媒体类型注册

本附录按照 BCP 13 [RFC4289] 以及W3C 规范注册互联网媒体类型, 为 MiniApp 包注册 application/miniapp-pkg+zip 媒体类型。

MiniApp 包文件是一种基于 [ZIP] 归档格式的容器技术,并包含一些修改。

类型名:
application
子类型名:
miniapp-pkg+zip
必需参数:
"N/A"
可选参数:
"N/A"
编码考量:
MiniApp 包是以 application/zip 媒体类型编码的二进制文件。 参见 RFC 6839 第 3.6 节 [RFC6839]。
安全性考量:
适用于 application/zip 的安全性考量同样适用于 MiniApp 包文件。处理 MiniApp 包文件的用户代理 应严格检查所获取数据的大小和有效性。当 MiniApp 包文件中存在数字签名时,用户代理SHOULD 实现必要机制,根据数字签名检查文件的完整性和 可信度,从而保护最终用户和托管平台免受包篡改或损坏带来的损害。更多信息参见7. 安全性考量
互操作性考量:
加入签名后,该文件不是标准 ZIP,但这种加入不会影响该文件作为 ZIP 文件的解析 和操作。
已发布规范:
此媒体类型注册用于 MiniApp 包,如位于 https://www.w3.org/TR/miniapp-packaging/ 的规范中所述。
使用此媒体类型的应用:
此媒体类型用于 MiniApp 的分发。支持(或计划支持)此媒体类型的应用和 软件平台的非穷尽列表如下: 上面列出的应用是用于开发本规范的基础技术。它们尚未使用 所提议的媒体类型,但当规范准备就绪时可能会支持它。该列表将稍后 确认/更新。
片段标识符考量:
"N/A"
附加信息:
此类型的已弃用别名:
"N/A"
魔数:
50 4B 03 04
文件扩展名:
MiniApp 通常以扩展名 .ma 标识。
Macintosh 文件类型代码:
ZIP
联系人及电子邮件地址以获取更多信息:
可通过 public-miniapps-wg@w3.org 联系 MiniApps 工作组
预期用途:
COMMON
使用限制:
"N/A"
作者:
MiniApp Packaging 定义了一种由 W3C MiniApp 工作组开发的文件格式。
变更控制者:
W3C 是 MiniApp Packaging 规范的控制者
临时注册?
"N/A"
议题 4:包的 ZIP 容器
本节需要指定 MIME 类型注册的技术细节(例如扩展名)。
说明

为了任何早期实现,一个临时方案可以是 application/x-w3c-miniapp-pkg+zip

议题

处理器是否应检查包的完整性(安全性考量一节)?

D. 参考文献

D.1 规范性参考文献

[BCP47]
语言识别标签。A. Phillips,编辑;M. Davis,编辑。IETF。2009 年 9 月。当前最佳实践。URL:https://www.rfc-editor.org/rfc/rfc5646
[CSS-SNAPSHOT]
CSS 快照。URL:https://www.w3.org/TR/CSS/
[ECMA-262]
ECMAScript 语言规范。 Ecma International。URL:https://tc39.es/ecma262/multipage/
[FETCH]
Fetch 标准。Anne van Kesteren。WHATWG。 现行标准。URL:https://fetch.spec.whatwg.org/
[HTML]
HTML 标准。Anne van Kesteren; Domenic Denicola;Dominic Farolino;Ian Hickson;Philip Jägenstedt;Simon Pieters。WHATWG。现行 标准。URL:https://html.spec.whatwg.org/multipage/
[INFRA]
Infra 标准。Anne van Kesteren;Domenic Denicola。WHATWG。现行标准。URL:https://infra.spec.whatwg.org/
[international-specs]
面向规范开发者的国际化最佳 实践。Richard Ishida;Addison Phillips。W3C。2024 年 10 月 17 日。W3C 工作组说明。URL:https://www.w3.org/TR/international-specs/
[JSON]
JavaScript 对象表示法(JSON)数据 交换格式。T. Bray,编辑。IETF。2017 年 12 月。互联网标准。URL:https://www.rfc-editor.org/rfc/rfc8259
[MIMESNIFF]
MIME 嗅探标准。Gordon P. Hemsley。WHATWG。现行标准。URL:https://mimesniff.spec.whatwg.org/
[MINIAPP-LIFECYCLE]
MiniApp 生命周期。Qing An; Haoyang Xu。W3C。2023 年 5 月 29 日。W3C 工作草案。URL:https://www.w3.org/TR/miniapp-lifecycle/
[MINIAPP-MANIFEST]
MiniApp 清单。Martin Alvarez-Espinar;Yongjing ZHANG。W3C。2024 年 11 月 14 日。W3C 工作草案。URL:https://www.w3.org/TR/miniapp-manifest/
[permissions]
权限。Marcos Caceres;Mike Taylor。W3C。2024 年 12 月 20 日。W3C 工作草案。URL:https://www.w3.org/TR/permissions/
[RFC2119]
用于 RFC 中表示 要求等级的关键词。S. Bradner。IETF。1997 年 3 月。当前最佳实践。URL:https://www.rfc-editor.org/rfc/rfc2119
[RFC4289]
多用途互联网邮件扩展(MIME) 第四部分:注册程序。N. Freed;J. Klensin。IETF。2005 年 12 月。 当前最佳实践。URL:https://www.rfc-editor.org/rfc/rfc4289
[RFC6839]
附加媒体类型结构化语法 后缀。T. Hansen;A. Melnikov。IETF。2013 年 1 月。资料性。URL:https://www.rfc-editor.org/rfc/rfc6839
[RFC8174]
RFC 2119 关键词中大写与小写的 歧义。B. Leiba。IETF。2017 年 5 月。当前最佳实践。URL:https://www.rfc-editor.org/rfc/rfc8174
[UAX15]
Unicode 归一化 形式。Ken Whistler。Unicode Consortium。2024 年 8 月 14 日。Unicode 标准附录 #15。URL:https://www.unicode.org/reports/tr15/tr15-56.html
[Unicode]
Unicode 标准。Unicode Consortium。URL:https://www.unicode.org/versions/latest/
[url]
URL 标准。Anne van Kesteren。WHATWG。 现行标准。URL:https://url.spec.whatwg.org/
[ZIP]
.ZIP 文件格式 规范。2020 年 7 月 15 日。最终版。URL:https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

D.2 资料性参考文献

[APK-SIGNATURE-V2]
APK 签名方案 v2。URL:https://source.android.com/security/apksigning/v2
[CHARMOD-NORM]
万维网字符模型:字符串 匹配。Addison Phillips 等。W3C。2021 年 8 月 11 日。W3C 工作组说明。 URL:https://www.w3.org/TR/charmod-norm/
[rfc1321]
MD5 消息摘要算法。 R. Rivest。IETF。1992 年 4 月。资料性。URL:https://www.rfc-editor.org/rfc/rfc1321
[rfc2315]
PKCS #7:加密消息语法版本 1.5。B. Kaliski。IETF。1998 年 3 月。资料性。URL:https://www.rfc-editor.org/rfc/rfc2315
[rfc2528]
互联网 X.509 公钥基础设施中 密钥交换算法(KEA)密钥在互联网 X.509 公钥基础设施证书中的 表示。R. Housley;W. Polk。IETF。1999 年 3 月。 资料性。URL:https://www.rfc-editor.org/rfc/rfc2528
[UAAG20]
用户代理可访问性指南(UAAG) 2.0。James Allan;Greg Lowney;Kimberly Patch;Jeanne F Spellman。W3C。2015 年 12 月 15 日。W3C 工作组说明。URL:https://www.w3.org/TR/UAAG20/
[X690]
Recommendation X.690 — 信息技术 — ASN.1 编码规则 — 基本编码规则(BER)、规范编码规则(CER)和可分辨编码规则 (DER)规范。ITU。URL:https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf