行政区划GeoJSON更新总是看到旧数据?静态文件指纹发布与files级精准刷缓存实战
行政区划 GeoJSON 更新老是"看到旧数据"?静态文件指纹发布与 files 级刷缓存才是正解
做省市区县这类 GeoJSON下载 站最烦的事之一:我明明把新版 geojson-series-XX 的边界文件传上去了,可用户隔天来问"怎么还是老的?"。查到最后十有八九不是源数据错,而是同名覆盖写 + 边缘缓存把旧文件当新文件吐给了用户。这篇把我踩过的坑和最终落地的"指纹发布 + 精准刷缓存"套路写清楚,全国省市区县geojson数据下载、全国省市区县区划边界数据下载、乃至全国村级geojson数据下载的更新都适用。
一、问题根源:同名写文件与"带参指纹"藏着的坑
第一版我图省事,直接对固定路径 data/county.json 做覆盖写,改完顺手刷一遍整站缓存。界面简单了,但隐患有两个:
- 中间态被读走。上传是逐个 R2 Key 写的,写一半时用户恰好 fetch 到这个文件,
JSON.parse直接崩,浏览器再一缓存旧版里带着半截内容就麻烦了。 - "刷新整站"误伤面很大。凡是同一前缀下没变的其它 JSON、页面、sitemap,跟着一起被清掉重捞,边缘回源一波全打满,成本上去是小事,搞不好触发边缘"智能重压"把没改的文件弄坏才真亏。
正确的做法是内容寻址(content-hash fingerprint):文件名带文件内容的哈希,例如 county.a3f9e2.html、geo/series-53.7c1d04.json。文件名一变,旧引用自然失效,浏览器与边缘都会去拉新文件,根本不需要"覆盖写 + 强刷"这条路。
// 生成期:按内容算短哈希,写进文件名;引用只记"当前指针"
import { createHash } from 'node:crypto';
import { readFileSync } from 'node:fs';
function publishAsset(rel, bytes) {
const h = createHash('sha1').update(bytes).digest('hex').slice(0, 8);
const key = rel.replace(/(\.[^.]+)$/, `.${h}$1`); // county.json -> county.7c1d04.json
// 伪码示意:此处由发布脚本把 bytes 写进 R2 的这个 Key
return `https://<host>/geo/${key}?v=${h}`;
}
但全站纯指纹也有缺点:行政区划页的 URL 要稳定,因为用户收藏、搜索收录都是不带指纹的干净地址 /articles/geojson-series-53。所以生产上是对稳定 URL 这套做"引用指针",不动 URL,彻底绕不开"改文件 + 刷新"时就只动精确的那几个。
二、稳定 URL 怎么更新:只有"变了的那几个文件"值得刷
行政区划这种 URL 稳定的场景,命中更新唯一靠谱的手段就是files 级精准刷新——说穿了就是"只清我明确改了的那几条 URL,其它一律不碰"。下面这张表是我给自己定的纪律,也建议想少踩坑的你照样子维护:
| 场景 | 允许动作 | 严禁动作 | 为什么不许 |
|---|---|---|---|
| 发新文章 | 刷该文章页 + 专栏首页 + sitemap_articles | 全站 / 整前缀 / 按 host 全站 | 会误伤同前缀其它没动文件 |
| 更新某省数据 | 刷该省页 + 该省 json | 整目录 / 整省下级全刷 | 其它未变化文件被强刷新,回源打满 |
| 换新版边界面 | 刷该地理页 + 引用它的列表页 | purge_everything 一键全清 | 一旦边缘"重压缩"就损文件 |
| 补发旧文 | 刷该补发文链接一条 | hostname 全站刷 | 与当期发布互相干扰 |
落在具体命令上,边缘加速那层的清除要写成单条 URL进 files 数组,逐条校验返回的 success,不是 true 就停下排查,绝不扩大范围重试第二次。很多线上事故都是"第一次失败后改成整站刷"埋下的。刷新要精准这一条,比"刷得勤"重要得多。
三、村级与多级钻取:引用失效比文件更新更隐蔽
到了全国村级geojson数据下载这种几十万要素、拆成镇级子文件的地方,最隐蔽的坑其实是引用失效:列表页 index 还指着旧镇文件的文件名,而新文件已经写好、也刷了缓存——但列表里没刷,用户点进去仍旧拉到旧的。归档类的场景反正不强求 URL 稳定,就全上指纹,靠"指针变了"天然完成版本释放,最省心。
落到我这套站点上的最终姿势是混合的:
1. 文章/列表等 SEO 稳定地址:正文用烘焙 HTML,更新时仅精准刷"文章页 + 专栏首页 + sitemap_articles"这几条(files 级,绝不整站); 2. 大数据文件:能带哈希的带哈希,不能带哈希的用"版本化目录 + 精准刷当日真正变化的 Key",上传永远只传 changed 文件,靠源站哈希审计确认没多传没漏传; 3. 收尾纪律统一:不管哪一层,都按"分文件上传 → files 级 / Type:file 单条 URL 刷新 → 校验成功再走下一步"的顺序,坚决不做 hostname 全站或 directory 型的大范围动作。
四、小结:别再"传了就以为更新了"
一句话收尾:行政区划 GeoJSON 更新的本质不是"把新文件传上去",而是"让所有引用在用户拿到的瞬间指向新内容"。做到这点只需要三件事——能指纹的就指纹、不能指纹的只刷真正变化的少数几条 URL、每一条都以 success 校验为准。这套东西我现在维护几十个文件级更新不再翻车,也建议做全国省市区县geojson数据下载或全国省市区县区划边界数据下载方向的朋友直接抄作业。
顺带说明本站口径:GeoJSON下载 的预览和数据表格是免费的,真要导出一份全量(含未化简的面、原始坐标精度的边界)才按 ¥1.99/次 收费,按需取用即可,别囤。坐标系、GeoJSON 格式、地图可视化这些基本功前面系列写过不少,这篇补的是"更新与释放"这一环,接上就稳了。