瓦片请求 404 或跨域被拦
地图框架加载正常,但底图是一格一格的灰色方块,网络面板里一片红色。
先看状态码
网络面板里的状态码能直接区分三类问题,不要凭猜。
| 状态码 | 含义 | 常见原因 |
|---|---|---|
| 404 | 地址不对 | URL 模板占位符写错、层级超出范围、瓦片不存在 |
| 403 | 无权访问 | Key 无效、配额用尽、Referer 不在白名单 |
| 200 但图片裂开 | 返回的不是图片 | 被跳转到登录页或错误页 |
| 控制台报 CORS | 跨域被拦 | 服务端没给 Access-Control-Allow-Origin |
404:先检查 URL 模板
瓦片地址里的 {z}、{x}、{y} 三个占位符缺一不可,
顺序也有讲究。有的服务用 {z}/{y}/{x},写成 {z}/{x}/{y}
就会请求到不存在的瓦片,表现为整片 404 或者画面拼接错乱。
// OpenStreetMap 与多数服务:z/x/y
'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
// TMS 规范:y 轴方向相反,需要翻转
'{z}/{x}/{-y}.png'
Leaflet 支持 {-y} 语法自动翻转,OpenLayers 则要在数据源里
设置 tileGrid 或用自定义 tileUrlFunction。
403:Key 与白名单
天地图、高德、腾讯都要求申请 Key,并且多数会校验来源域名。
本地开发时如果 Referer 是 localhost 或 file://,
经常被判定为非法来源。
| 检查项 | 做法 |
|---|---|
| Key 是否有效 | 把瓦片 URL 单独贴到浏览器地址栏打开,看能否出图 |
| 域名白名单 | 到控制台把开发域名和线上域名都加上 |
| 配额 | 查看当天调用量是否已超限 |
| 协议 | 部分服务只允许 HTTPS |
CORS:不是所有瓦片都要它
普通 <img> 加载图片不受 CORS 限制。但以下场景会触发:
- 用
fetch或XHR自己取瓦片再转成图片 - 开启
crossOrigin为了后续导出 canvas 图片 - canvas 里绘制瓦片后要
toDataURL
如果只是展示,不要开启 crossOrigin,能绕开很大一部分跨域问题。
需要导出图片时,就必须让瓦片服务支持 CORS,或者改成代理转发。
// 需要导出图片时才加这一项
L.tileLayer(url, {
crossOrigin: 'anonymous'
}).addTo(map);
加一个兜底提示
瓦片失败时地图框架不会中断,只会默默留白。线上环境应该监听错误事件, 把情况告诉用户,而不是让人对着灰块猜。
var errors = 0;
layer.on('tileerror', function () {
errors++;
if (errors === 3) {
document.getElementById('tip').textContent = '底图加载失败,请检查网络或 Key 配置';
}
});
排查顺序
- 网络面板看状态码,先分清 404 / 403 / CORS
- 单个瓦片 URL 直接在浏览器打开,验证地址本身是否有效
- 404 查占位符顺序和 y 轴翻转
- 403 查 Key、白名单、配额、协议
- CORS 只在需要导出图片时才处理,其余情况去掉 crossOrigin
经纬志(2026)。《瓦片请求 404 或跨域被拦》。https://www.jingweizhi.com/cookbook/tile-404-cors.html(访问日期 2026-11-03)。