样式加载失败,地图一直是灰底
地图能出现,也能拖动,但只有一个灰色背景,道路、水系、标注全都没有。
现象
控制台给出样式加载失败的信息,map.isStyleLoaded() 始终为 false:
Error: Could not load style: https://styles.example.cn/basic/style.json
at Style.load (style.ts:673)
Uncaught Error: style is not done loading
同时所有 addLayer 调用都抛错,因为样式还没就绪。
原因
| 原因 | 网络面板表现 |
|---|---|
| style.json 路径写错或服务未部署 | 404 |
| 跨域未放行 | 请求被 CORS 拦截,无响应头 |
style.json 里 sprite、glyphs 路径不可达 | style.json 200,但后续 404 |
| JSON 语法错误 | 200,解析报 Unexpected token |
| 内网证书过期 | net::ERR_CERT_AUTHORITY_INVALID |
排查过程
先注册 error 事件,把被静默吞掉的错误打出来。MapLibre 的很多失败
只会通过这个事件通知:
map.on('error', function (e) {
console.error('地图错误', e.error && e.error.message, e.sourceId, e.tile);
});
然后直接访问样式地址:
fetch('/styles/basic/style.json')
.then(function (r) {
console.log('状态', r.status, '类型', r.headers.get('content-type'));
return r.json();
})
.then(function (s) {
console.log('sprite', s.sprite, 'glyphs', s.glyphs);
})
.catch(function (err) { console.error('样式不可用', err); });
解决方案
本地样式放在与页面同源的目录下,sprite 与 glyphs
用绝对路径,避免相对路径按 style.json 所在目录解析而错位:
{
"version": 8,
"name": "basic",
"sprite": "/styles/basic/sprite",
"glyphs": "/fonts/{fontstack}/{range}.pbf",
"sources": {
"base": {
"type": "vector",
"tiles": ["/tiles/base/{z}/{x}/{y}.pbf"],
"minzoom": 0,
"maxzoom": 14
}
},
"layers": [
{ "id": "bg", "type": "background", "paint": { "background-color": "#f2f4f6" } }
]
}
样式确实不可用时,给一个最少可用的内联样式作为兜底, 保证地图先能显示,再异步替换:
var fallbackStyle = {
version: 8,
sources: {},
layers: [{ id: 'bg', type: 'background', paint: { 'background-color': '#e9edf2' } }]
};
var map = new maplibregl.Map({
container: 'map',
style: fallbackStyle,
center: [116.391, 39.907],
zoom: 11
});
fetch('/styles/basic/style.json')
.then(function (r) { return r.json(); })
.then(function (style) { map.setStyle(style); })
.catch(function (e) { console.error('保留兜底样式', e); });
addLayer 必须等样式就绪。用 load 事件或用
style.load,不要写在构造函数之后:
map.on('load', function () {
map.addSource('poi', { type: 'geojson', data: '/data/poi.geojson' });
map.addLayer({ id: 'poi', type: 'circle', source: 'poi' });
});
验证
map.isStyleLoaded() 在 2 秒内变为 true。
底图出现道路与注记,map.getStyle().layers.length 大于 0。
控制台不再出现 style is not done loading。
别忽略 sprite:样式主体正常但图标、箭头全缺失,多半是 sprite
指向的资源 404。style.json 里只写前缀,不带 .json 与 .png,
MapLibre 会自己拼出三个文件。
经纬志(2026)。《样式加载失败,地图一直是灰底》。https://www.jingweizhi.com/cookbook/maplibre-style-load-fail.html(访问日期 2026-11-03)。