首页 / 实战手册 / 瓦片
天地图瓦片 403,Key 是对的但 Referer 不在白名单
先看结论
把瓦片地址贴到浏览器地址栏能打开,放进地图里就全部 403。
现象
网络面板里对 t{0-7}.tianditu.gov.cn/vec_w/wmts 的请求全部返回
403 Forbidden,响应体是一段 HTML:
<html>
<head><title>403 Forbidden</title></head>
<body><h1>403 Forbidden</h1><p>Invalid referer</p></body>
</html>
把同一个 URL 粘贴到地址栏回车,能正常看到瓦片图片。
换成本地 file:// 打开页面,情况一样。
原因
天地图对 Key 做来源校验:比对请求头里的 Referer 是否在控制台配置的白名单域名内。
- 地址栏直接访问不发
Referer,校验被跳过,所以能打开。 localhost:5173、127.0.0.1、file://默认都不在白名单里。- 白名单只写了
example.com时,www.example.com不一定匹配,取决于是否配置了子域名。
排查过程
- 在开发者工具的请求详情里看
Request Headers → Referer,确认实际值。 - 到天地图控制台看该 Key 绑定的域名列表,逐字比对(含端口、是否带 www)。
- 用
curl带不同 Referer 试一次,确认服务端行为。 - 排查是否有代理或本地 hosts 改写,导致 Referer 与预期不同。
# 带合法 Referer,应返回 200
curl -I -H "Referer: https://example.com/" ^
"https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=10&TILEROW=392&TILECOL=843&tk=你的key"
# 不带 Referer 也可能 200,容易被误判为 Key 没问题
curl -I "https://t0.tianditu.gov.cn/vec_w/wmts?..."
解决方案
开发环境把 localhost 加进白名单;不能改白名单时走同源代理,
让浏览器请求自己的域名。
// vite.config.js:开发代理,浏览器只看到 /tdt/...
export default {
server: {
proxy: {
'/tdt': {
target: 'https://t0.tianditu.gov.cn',
changeOrigin: true,
rewrite: p => p.replace(/^\/tdt/, '')
}
}
}
};
// 页面里用同源地址
L.tileLayer('/tdt/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0' +
'&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles' +
'&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=你的key', {
subdomains: [],
maxZoom: 18
}).addTo(map);
生产环境不要用代理绕过校验。把正式域名加进白名单是唯一稳妥的做法, 代理只是开发期的权宜手段,且会放大服务端流量。
验证
请求返回 200 且 Content-Type: image/jpeg;
地图上八个子域名的瓦片都能加载,tileerror 事件不触发。
let err = 0;
layer.on('tileerror', () => { if (++err === 1) console.warn('仍有瓦片 403'); });
// 加载后 err 应为 0
适用版本
| 组件 | 版本 | 说明 |
|---|---|---|
| 天地图 WMTS | 1.0.0 | 矢量 vec_w、影像 img_w,子域 t0~t7 |
| 天地图 Key | 浏览器端 / 服务端 | 浏览器端 Key 必须配域名白名单 |
| Leaflet | 1.9.x | subdomains 需显式设为 ['0'..'7'] |
经纬志(2026)。《天地图瓦片 403,Key 是对的但 Referer 不在白名单》。https://www.jingweizhi.com/cookbook/tile-403-referer.html(访问日期 2026-11-03)。