WebGIS 上线检查清单:那些在生产环境才会暴露的坑
本文不讲怎么写代码,讲怎么让代码在生产环境不崩。大部分 WebGIS 事故的根因是同一批问题。
开发环境和生产环境的十道断层
每个 WebGIS 项目都会经历一次"从能跑"到"崩掉"的转变,而且往往发生在上线第一天。断层主要在十个地方。
1. 地图容器没有明确尺寸
最经典也最致命的问题:
#map { /* 没有 height */ }父容器高度是 auto,地图容器高度塌陷为 0,页面上什么都看不到,且控制台没有任何报错。
/* 地图容器必须有确定高度 */
#map {
height: 100vh; /* 或具体像素值 */
width: 100%;
}这个问题会浪费初学者整整一个下午,而它的表现是"代码没错但页面空白"。
2. 瓦片服务不可用或不合规
上线前必须确认:
瓦片地址稳定可访问,服务条款允许你的使用方式
有 HTTPS,加载在 HTTPS 页面下
署名(attribution)已按要求展示
有失败兜底——瓦片 404 时不是白屏,而是有降级底色或提示
商业地图服务的免费额度滥用会导致密钥被封,这在生产环境是常见事故。做一张开发用的地图和一个日均百万 PV 的地图,用量差三个数量级。
3. Mixed Content:HTTPS 页面加载 HTTP 资源
现代浏览器会直接拦截这类请求,控制台报:
Mixed Content: The page at 'https://...' was loaded over HTTPS,
but requested an insecure resource 'http://...'后果是资源根本不加载,功能静默失效。 开发环境用 HTTP 时不会遇到,上线切 HTTPS 后突然全挂。
排查方式:上线后立即全站检查浏览器控制台,不只是自己常用的那个浏览器。
4. CORS 配置
跨域问题在本地开发时常常不出现——因为同源。上线后前端域名和数据服务域名不同,立刻炸。
# Nginx 为瓦片服务加 CORS 头
location /tiles/ {
add_header Access-Control-Allow-Origin "*";
add_header Cache-Control "public, max-age=3600";
}注意:加了 CORS 头之后,文件类型会触发预检请求(OPTIONS),Nginx 配置不当会返回 405。这类问题只在跨域时暴露。
5. 路径问题
本地开发时 ./ 指向项目根目录,部署到子路径 /console/dashboard/ 之后,./js/ 就指向了 /console/dashboard/js/——404。
解决方案是用绝对路径或构建期注入 base:
// vite.config.js
export default {
base: '/your-app/', // 部署时改这里
};6. 坐标系统一性
见《网络地图坐标系完全指南》。最常见的错误是:GPS 采集的 WGS-84 数据直接标到高德底图上,偏移 50-500 米,且不会报错,用户只会觉得"位置不准"。
上线前用几个已知坐标做基准测试:北京天安门 WGS-84 约 (116.397, 39.917),转换到 GCJ-02 后再在高德上落点,应该精确在天安门广场上。
7. 数据量失控
开发时用 100 条测试数据,线上跑真实数据才发现问题。
// ❌ 一次性加载所有要素
const all = await fetch('/api/all-features').then(r => r.json());
// ✅ 按视口 + 缩放级别请求
map.on('moveend', debounce(async () => {
const b = map.getBounds();
const features = await fetch(
`/api/features?bbox=${b.getWest()},${b.getSouth()},${b.getEast()},${b.getNorth()}` +
`&z=${Math.round(map.getZoom())}`
).then(r => r.json());
updateLayer(features);
}, 300));moveend 必须防抖,否则用户拖动地图时每帧都发请求。
8. 错误处理缺失
// ❌ 静默失败
map.on('error', () => {});
// ✅ 至少记录
map.on('error', (e) => {
console.error('[MapLibre]', e.error);
reportError(e.error); // 上报监控
});关键服务失败要有用户可见的提示。 瓦片加载失败时显示"地图数据加载失败,请刷新重试",比用户对着白屏猜要友好得多。
9. 内存泄漏
长会话场景(运维大屏、监控平台)的典型问题:
// ❌ 每次筛选都叠加一个新的图层
map.addSource('filter-' + Date.now(), { ... });
// ✅ 复用同一个 source
if (!map.getSource('filtered')) {
map.addSource('filtered', { type: 'geojson', data: ... });
}
map.getSource('filtered').setData(newData);判据:页面挂机几小时后内存持续增长且不回落,就是泄漏了。用 Chrome DevTools 的 Memory 面板做 heap snapshot 对比。
10. 第三方密钥与服务条款
最后一条,也是最容易上生产的:
第三方地图服务的密钥在前端可见——这是正常的,但必须做域名白名单和配额管理
定期检查服务条款是否有调用频率限制
保留降级方案:如果主服务挂了,有没有备用底图
发布前完整检查清单
功能
[ ] 地图容器有明确宽高
[ ] 所有核心交互在生产域名下正常
[ ] 坐标系统一,无偏移
[ ] 数据更新链路验证(静态文件 / 接口 / 数据库查询)
性能
[ ] 首屏加载时间可接受(建议 99% |
常见事故速查
一条经验法则
WebGIS 的问题几乎不会在开发环境暴露。 开发环境的数据是干净的、量是小的、网络是快的、坐标系是统一的、HTTPS 是可选的。
真正的验证只能在一个像生产环境的地方做。 如果条件允许,用生产数据库的一个脱敏副本,用生产域名和 HTTPS 协议,在真实网络条件下完整走一遍。
参考资料
MapLibre GL JS 文档 — https://maplibre.org/
Leaflet 文档 — https://leafletjs.com/docs/
OpenLayers 文档 — https://openlayers.org/doc/
MDN Mixed Content 说明 — https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content
常见 CORS 配置说明 — https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS