---
title: "WebGL应用平台能力接口"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/webgl-platform-capability-api/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/05-游戏图形与运行时/WebGL/WebGL应用平台能力接口.md"
content_hash: cff1c5737d322d6b80256e15bdbc0e9eab8a3c5efb8225be5631b1c46d9d808c
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# WebGL应用平台能力接口

﻿# WebGL应用平台能力接口


## 引言: Web平台能力接口

```text
平台能力接口（Browser / MiniApp API）
        ▲
        │ 由规范形式化
        │
Web IDL（接口描述语言）
        ▲
        │ 被宿主实现并注入
        │
宿主（浏览器、微信 App、抖音 App…）
```

Web 页面和各类 MiniApp 脚本都不是裸跑在 ECMAScript 引擎里，而是依赖宿主（浏览器、微信 App、抖音 App …）注入的 **“平台能力接口”**。理解它们的**定义方式**、**使用方式**与**底层实现**，是写出跨端、可维护代码的前提。

**平台能力接口**：浏览器或小程序宿主在 **JavaScript 运行环境** 中注入的一组函数 / 对象，向脚本暴露网络、存储、渲染、系统能力等。
**核心特征**：

1. 入口是 **全局单例对象**；
2. 业务脚本 **无需 import**；
3. 真正实现位于 **宿主的原生层（C++/Java/Obj-C/Rust…）**。

| 宿主    | 全局对象                               | 运行时何时注入                      |
| ----- | ---------------------------------- | ---------------------------- |
| 浏览器   | `window`（含 `document`、`fetch()` …） | 浏览器进程初始化 JS 引擎后立即注入          |
| 微信小程序 | `wx`                               | 在 WebView 创建脚本上下文前由微信 App 注入 |
| 抖音小程序 | `tt`                               | 同上，由抖音 App 注入                |
| …     | …                                  | …                            |


## 规范定义：Web IDL（Web Interface Definition Language）

Web IDL（Web Interface Definition Language）：一门专门为 _Web 平台_ 设计的 _接口描述语言_ （IDL），由 WHATWG 维护为 _Living Standard_ ，W3C 也有准同步版本。其目标是：用一套与编程语言无关的语法，把浏览器要提供给 JavaScript 的 API 定义得 _精确、可测试、可生成绑定代码_ 。

早期规范用自然语言描述 DOM、XHR 等接口，结果各浏览器对同一属性的类型、可空性、默认值等细节解释不同，导致互操作问题。Web IDL 让这些细节（类型转换、异常、可选参数、Promise 处理等）机器可读，从而：
1. 规范作者能一致地写 API；
2. 浏览器实现者可自动生成 C++/Rust ↔ JS 的“胶水”代码；
3. 文档站（MDN）、类型系统（TypeScript lib.dom.d.ts）和测试框架可以直接解析 IDL。


规范到浏览器的路径：
1. 规范发布 → 浏览器拉取最新 Web IDL 列表；
2. 工具（如 _Blink’s IDL compiler_、_Gecko’s WebIDLCodegen_）把 IDL 生成 C++/Rust 绑定：创建 JS **interface object**、实现属性 getter/setter、参数校验；
3. JS 引擎通过绑定层把调用转发给内部实现（网络栈、DOM 等）。

给开发者的影响：
- **一致的 API 形状**：不同浏览器对 `fetch()`、`AbortSignal` 等接口的签名完全一致；
- 类型定义可被 TypeScript、Flow、Rust wasm-bindgen 等再利用，实现强类型提示；
- 测试框架 (WPT) 能自动生成“接口存在性”断言。

## API 的生态与标准化现状


问：这些 API 有统一标准吗？

| 生态                           | 标准化现状                                                                                                                    | 规范出处                                                                                                                                                                                                                                                                                                           | 兼容度现状                      |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| **Web（浏览器）**                 | **完全标准化**：WHATWG/W3C 在 HTML、DOM、Fetch 等规范里通过 **Web IDL** 精确定义每个接口                                                        | 例：Fetch Standard Living Spec ([fetch.spec.whatwg.org](https://fetch.spec.whatwg.org/?utm_source=chatgpt.com "WHATWG - Fetch Standard"))                                                                                                                                                                        | 主要浏览器实现一致                  |
| **MiniApp（微信 / 抖音 / 支付宝 …）** | **各家先行 → W3C 正在收敛**：API 由各平台先各自设计；2019 年起 W3C 成立 **MiniApps WG**，正把共性沉淀成系列规范（Packaging、Manifest、Lifecycle、API Profile 等） | • MiniApp Packaging WD ([W3C](https://www.w3.org/TR/miniapp-packaging/?utm_source=chatgpt.com "MiniApp Packaging - World Wide Web Consortium (W3C)")) • MiniApp Specs 一览 (W3C) ([W3C GitHub](https://w3c.github.io/miniapp/specs/?utm_source=chatgpt.com "MiniApp Specifications \| miniapp - w3c.github.io")) | 目前仍以厂商文档为准；同名接口大多“形似、细节不同” |

**厂商官方文档示例**: 抖音 `tt.request()` API 文档 ([developer.open-douyin.com](https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/network/http/tt-request/?utm_source=chatgpt.com "tt.request_小程序_抖音开放平台"))

## 示例剖析：**`wx` API**（MiniApp）

**`wx` 是什么？**
   * 它是 **WeChat Mini Program 运行时** 在加载脚本前注入的 **全局单例对象**。
   * 其内部保存了一张 *命令→native 调用* 的路由表，并附带常量、枚举、内部缓存等。

**作用**
   * **API 集合入口**：大多数小程序能力（网络、存储、文件、蓝牙、云开发等）都以 `wx.<method>` 形式公开。
   * **事件/钩子注册器**：如 `wx.onError`、`wx.onNetworkStatusChange` 等监听接口同样挂载在 `wx`。

**所有 API 都在 `wx` 上吗？**
   * **绝大多数** 通用能力是的。
   * 但还有三类例外：
     1. **生命周期构造器**：`App()`, `Page()`, `Component()` —— 用来声明应用/页面/组件本身。
     2. **增强 API**：插件、云开发 (`wx.cloud` 子命名空间)、小游戏 (`wx.game.*`) 在 `wx` 下再分级。
     3. **Worker 与 ES 模块**：在独立沙箱脚本中可能无法直接访问主环境的 `wx`，需通过 `self.wx` 或 `importScripts('wx.js')` 暴露的 shim。


**注册 `wx.onError(cb)` 时发生的事**
   * 运行时把 `cb` 存入监听表。
   * 当 **JS 引擎** 抛出未捕获异常或 **Native 层** 上报崩溃摘要时，Bridge 会序列化错误信息 → 主 JS 线程 → 依次调用注册的回调。
   * 回调内若希望阻止默认错误提示，可返回 `true` 或调用 `console.error` 后自行上报。


## 从脚本到系统：底层调用链

```text
┌───────────────────────────────┐
│   JavaScript 代码（前端）      │   ► 调用 JS API
└──────────────┬────────────────┘
               ▼
┌──────────────┴────────────────┐
│  JS ↔ Native 绑定/Bridge 层   │   ► 形态取决于宿主
│  • 浏览器：Web IDL + V8/JSValue│  • 小程序：JSON/二进制消息队列
└──────────────┬────────────────┘
               ▼
┌──────────────┴────────────────┐
│     宿主 Native 实现层         │   ► 线程池 / 网络栈 / GPU / …
│  • Blink / Gecko / WebKit     │  • 微信 App (OKHttp, NSURLSession…)
└──────────────┬────────────────┘
               ▼
┌──────────────┴────────────────┐
│       OS / 硬件服务            │   ► TCP/IP、文件系统、OpenGL ES…
└───────────────────────────────┘
```

|             | **Browser API** (`window.fetch`, `window.onerror`, …)  | **Mini-Program API** (`wx.request`, `wx.onError`, …) |
| ----------- | ------------------------------------------------------ | ---------------------------------------------------- |
| **接口规范**    | W3C/WHATWG 定义，使用 **Web IDL** 描述属性与方法                   | 腾讯自定义 MDN-style 文档；无统一规范组织                           |
| **JS 宿主对象** | `window`（同时承载 BOM、DOM、Web API）                         | `wx` **＋** 全局构造器 `App / Page / Component`            |
| **绑定方式**    | 编译生成 C++/Rust glue，将 V8 `v8::Object` ↔ native 对象       | 手写或代码生成的 **Bridge**，JS ↔ Native 通过 JSON/二进制消息        |
| **线程模型**    | 主线程负责 JS + DOM；I/O 与 GPU 在独立线程/进程                      | JS 运行在单独 V8 线程；网络/GPU/文件在宿主线程池                       |
| **回调返回**    | DOM 事件队列 & 微任务；Promise Resolution                      | Bridge 将结果投递到 JS **Callback 队列** 或 Promise           |
| **错误捕获**    | JS 异常 → `window.onerror` / `addEventListener('error')` | JS 异常 → `wx.onError`Native 崩溃 → `App.onError`    |
| **核心思想**    | **Web IDL × 单一全局对象** 把平台能力映射到 JS                       | **小型 SDK** 将平台能力聚合到 `wx`，外加若干生命周期钩子                  |


* **Browser API**：由浏览器内核实现，借助 **Web IDL** 挂到 `window`；JS 引擎仅负责执行语言本身。
* **Mini-Program API**：由宿主 App 用 Native 代码实现，通过 **`wx` 全局对象 + Bridge** 向脚本暴露；`wx` 既是命名空间也承担事件总线的角色，但构造器 (`App/Page/Component`) 和部分子域另作补充。这样就把“Web API” 的设计理念迁移到小程序沙盒中，实现了跨端一致的调用体验。


### 在**浏览器 (Web)** 里的机制


| 层级             | 作用 / 关键点                                                             | 代码/技术栈                                     | 归属                          |
| -------------- | -------------------------------------------------------------------- | ------------------------------------------ | --------------------------- |
| ECMAScript 运行时 | `try … catch`、`Promise` 等，只描述语法和执行语义                                 | V8、SpiderMonkey、JavaScriptCore…            | **JS 引擎**                   |
| Web IDL 绑定层    | `window.onerror`、`XMLHttpRequest`、`fetch()`、`addEventListener` 等接口签名 | Web IDL ➜ 生成 C++/Rust/Objective-C 绑定代码     | **宿主 (浏览器内核, Bindings子模块)** |
| 内核模块(浏览器内部实现)  | 事件派发、网络栈、线程/进程隔离、沙箱                                                  | Blink / Gecko / WebKit (C++/Rust) + OS 网络库 | **宿主 (浏览器内核)**              |
| JS 回调          | `onerror` 或 Promise `resolve/reject`                                 | 业务 JS                                      | 脚本                          |

#### 例1: `window.onerror` 发生了什么？

1. **JavaScript 运行时**在执行脚本或事件回调时抛出未捕获异常。
2. JS 引擎把异常对象上浮到 **绑定层**：

```cpp
// 伪码 in V8 bindings
v8::TryCatch try_catch(isolate);
RunScript();
if (try_catch.HasCaught()) {
   DispatchJSEvent("error", try_catch.Exception());
}
```

3. 绑定层调用 **DOM 事件系统**（C++）创建一个 `ErrorEvent`，并按 *Web IDL* 定义把 `message / filename / lineno / colno / error` 填进去。
4. DOM 事件系统按照 **事件流** 规则逐级冒泡；如果在 `window` 对象上发现 `onerror` 属性存在可调用函数，就在主线程回调它。
5. 若 `onerror` 返回 `true` 或 `event.preventDefault()`，浏览器会阻止默认的错误提示；否则控制台输出 error。

> **关键点**：`window.onerror` 并非 ECMAScript 规范，而是浏览器在 *宿主层* 用 C++/Rust 实现并通过 Web IDL 暴露的 **Web API**。

#### 例2: `fetch()` / `XMLHttpRequest`

* **JS → C++ 边界**：调用时传入 JS 对象；绑定层生成网络请求描述，放入 **NetworkService** 线程/进程。
* **网络栈**：Blink/Chromium 使用 **net/** 模块，加上 QUIC/HTTP2/TLS 实现；Gecko 使用 Necko。
* **Promise**：`fetch()` 返回 JS Promise；C++ 网络回包后通过 **microtask queue** 向 JS 线程投递 `resolve`/`reject`，再执行回调。

---

### 在 **小程序 (如微信/支付宝) WebGL Runtime** 里的机制

> 小程序的 JS 运行时（通常是 **V8 (Android)** / **JavaScriptCore (iOS)**）嵌在 App 内；Web API 子集由宿主 App 用 **Native+C++/Obj-C/Java/Kotlin** 实现，并通过 **JS–Native Bridge** 暴露给脚本。Unity WebGL 的“小游戏”运行时亦遵循同思路。


| 层级         | 作用 / 关键点                           | 代码/技术栈                                   | 归属             |
| ---------- | ---------------------------------- | ---------------------------------------- | -------------- |
| JS 调用      | `wx.request({ … })`                | V8 / JSC                                 | **JS 引擎**      |
| Bridge     | 参数 JSON 化 → Native                 | C++, Java/Kotlin, Obj-C                  | 宿主App(Bridge层) |
| Native 网络栈 | OKHttp / NSURLSession              | Java/Kotlin (Android), Obj-C/Swift (iOS) | 宿主App(Native层) |
| 回抛         | JSON → JS 线程 → `success`/`fail` 回调 | 业务 JS                                    | JS 脚本          |


#### 例1: `wx.request()` 工作流程

1. **前端脚本** 调用 `wx.request({url, success, fail, complete})`.
2. **JS–Native 桥** 把参数序列化成 JSON，送到 **宿主线程**。
3. 宿主用 **OKHttp / NSURLSession** 发网络请求。
4. 回包后，宿主线程把结果再次序列化成 JSON，通过队列抛回 **JS 线程**。
5. Runtime 把 JSON 解析成 JS 对象并执行 `success` 回调；如果网络/解析异常，执行 `fail` 并触发全局 `App.onError`。

#### 例1: `App.onError`

* 在 iOS/Android 原生侧通过捕获 **Objective-C Exception, Java Exception, Signal** 等，把崩溃信息写入 JS 引擎特定对象并触发 JS 回调。
* 对于 **JS 代码异常**（类似浏览器的未捕获异常），Runtime 会通过 `V8::MessageListener` / `JSC::exception` 捕获并转调 `onError`（守护线程与宿主线程通信即可）。


---

## 总结：**“JS 运行时 vs 宿主” 责任划分**

| 功能                             | ECMAScript 引擎 (V8/JSC) | 宿主环境 (Browser / 小程序 App) |
| ------------------------------ | ---------------------- | ------------------------ |
| 解析 & 执行 JS 语法                  | ✔                      | ✘                        |
| 管理事件循环宏/微任务                    | ✔ (内部实现)               | 提供额外任务源 (I/O, timer)     |
| 全局错误捕获 `onerror`/`App.onError` | 将异常上浮                  | 创建 Event / 回调到 JS        |
| 网络 I/O (`fetch`, `wx.request`) | ✘                      | ✔ (网络栈 + 结果回调)           |
| Canvas/WebGL 渲染 & DOM          | ✘                      | ✔ (GPU/Skia/OpenGLES)    |
| 文件、系统能力                        | ✘                      | ✔ (Native 调用)            |

* **JS 引擎** 只负责 *语言*；所有环境能力（DOM、网络、文件、摄像头）都由 **宿主** 提供。
* 宿主通过 **Web IDL**（浏览器）或 **桥接协议**（小程序）把这些能力映射为 JS 可调用对象。
* “浏览器 API” 与 “小程序 API” 路径大同小异：**JS → 绑定 → 宿主 native layer → 系统服务 → 回调 → JS**。

希望这张“分层图 + 调用链”能澄清 onerror/request 等接口的 **归属** 与 **底层实现**。若你需要更深入到特定引擎（如 Chromium `blink::V8ErrorHandler` 或 Unity WebGL `JS_LIBRARIES/*.js`）的源码路径，可告诉我再展开。
