网络和 AJAX
本文档解释了 Mapbox GL JS 如何处理网络请求,包括身份验证、请求转换和缓存策略。该库发出许多请求以加载渲染交互式地图所需的地图瓦片、样式、sprites、字体和其他资源。
网络架构概述
Mapbox GL JS 采用全面的网络系统来加载渲染地图所需的各种资源。该库需要高效地获取多种类型的数据,通常是并行获取,同时适当地处理身份验证、缓存和错误情况。
资源类型
Mapbox GL JS 加载各种资源类型,每种都有自己的请求模式和处理逻辑。该库使用 ResourceType 枚举对这些不同的资源进行分类。
| Resource Type | Description | URL Pattern Example |
|---|---|---|
| Style | 地图样式规范 | mapbox://styles/mapbox/streets-v11 |
| Source | Source 数据,如矢量瓦片 | mapbox://mapbox.mapbox-streets-v8 |
| Tile | 单个地图瓦片 | mapbox://tiles/{z}/{x}/{y} |
| Glyphs | 用于文本的字体字符 | mapbox://fonts/{fontstack}/{range}.pbf |
| Sprite | 地图中使用的图标 | mapbox://sprites/mapbox/streets-v11 |
| Image | 自定义图标的图像 | 用户定义的 URL |
| Video | 动态地图的视频 Source | 用户定义的 URL |
该库适当地处理每种资源类型,对每种都有特定的解析逻辑和错误处理。
来源: CHANGELOG.md、README.md
请求流生命周期
下图说明了 Mapbox GL JS 中网络请求的完整生命周期,从初始化到渲染:
身份验证和请求转换
Mapbox GL JS 通过请求转换函数提供灵活的请求处理。此功能允许开发人员在发送请求之前修改请求,从而实现自定义身份验证、标头和其他修改。
请求参数
RequestParameters 接口定义了请求的结构:
interface RequestParameters {
url: string;
method?: string;
headers?: {[key: string]: string};
body?: string;
type?: 'string' | 'json' | 'arrayBuffer';
credentials?: 'same-origin' | 'include';
collectResourceTiming?: boolean;
}请求转换
RequestTransformFunction 类型允许开发人员修改传出请求:
type RequestTransformFunction = (url: string, resourceType: ResourceType) => RequestParameters;可以将此函数提供给 map 选项以转换所有传出请求:
身份验证示例
Mapbox GL JS 需要身份验证才能向 Mapbox 服务发出请求。这通常可以通过几种方式提供 access token:
- 作为 Map 构造函数中的 token 参数
- 通过请求转换
- 通过 mapboxgl.accessToken 全局属性
来源: CHANGELOG.md
缓存策略
Mapbox GL JS 利用浏览器缓存和自己的缓存机制来优化性能并减少带宽使用。
浏览器缓存
默认情况下,瓦片请求的响应根据其 HTTP 标头进行缓存。该库遵循标准的缓存控制标头,如 Cache-Control 和 Expires。
本地存储缓存
对于瓦片数据,Mapbox GL JS 可以将瓦片存储在浏览器的本地存储中,由 volatile source 属性控制:
volatile 属性控制瓦片是否存储在本地存储中:
volatile: true(默认): 瓦片不存储在本地存储中volatile: false: 瓦片存储在本地存储中以提高离线性能
错误处理
Mapbox GL JS 实现了对网络请求的全面错误处理。当请求失败时,该库:
- 发出错误事件,其中包含有关失败的详细信息
- 尝试重试某些类型的请求(例如瓦片请求)
- 当无法加载资源时优雅降级
例如,如果样式资源加载失败,该库将发出错误但继续使用默认样式运行。如果瓦片数据加载失败,该库将显示其拥有的数据,同时继续尝试加载缺失的瓦片。
发出自定义请求
对于需要使用自定义数据源扩展 Mapbox GL JS 的应用程序,该库公开了几个用于发出自定义请求的接口。
GeoJSON Source 示例
使用带有 URL 的 GeoJSON source 时,Mapbox GL JS 将自动获取数据:
map.addSource('my-data', {
type: 'geojson',
data: 'https://example.com/data.geojson'
});自定义请求转换
要获得更多控制,您可以实现自定义请求转换函数:
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
transformRequest: (url, resourceType) => {
if (resourceType === 'Source' && url.startsWith('https://myapi.example.com')) {
return {
url: url,
headers: { 'Authorization': 'Bearer ' + myApiKey },
credentials: 'same-origin'
};
}
}
});这允许向特定请求添加身份验证或其他修改,同时保持其他请求不变。
优化网络性能
Mapbox GL JS 实施了几种策略来优化网络性能:
- 并行加载: 该库并行加载多个资源以最小化加载时间
- 预加载: 可以预加载与当前视图相邻的瓦片以改善平移体验
- 请求优先级: 可见瓦片等关键资源优先于不可见资源
- 响应大小优化: 矢量瓦片经过压缩以最小化带宽使用
- 取消: 不再需要的资源(例如,当地图视图发生重大变化时)的请求可以被取消
来源: CHANGELOG.md
高级用例
自定义协议
Mapbox GL JS 支持资源 URL 的自定义协议,从而能够与各种后端系统集成:
mapbox://: 来自 Mapbox 服务的资源http://和https://: 标准 Web 资源- 自定义协议: 可以使用请求转换函数处理
离线支持
通过利用缓存功能并控制 volatile 属性,应用程序可以实现离线支持:
- 使用自定义逻辑预缓存所需的瓦片
- 在 sources 上设置
volatile: false以启用本地存储缓存 - 实现请求转换函数,在离线时提供缓存资源
来源: style-spec/CHANGELOG.md
总结
Mapbox GL JS 提供了一个灵活且强大的网络系统来处理交互式地图所需的各种资源。通过了解请求流、转换能力和缓存策略,开发人员可以优化地图加载性能并自定义网络行为以满足其应用程序的特定需求。
该库的架构允许:
- 自定义身份验证
- 请求修改
- 健壮的缓存
- 错误处理
- 性能优化
这些功能使其适用于广泛的应用程序,从简单的地图到具有自定义数据源和离线功能的复杂数据可视化。