Skip to content

内网高德地图代理问题

内网离线可用|高德地图私有化部署两种代理方案实战对比(Node反向代理 + ServiceWorker拦截)

一、前言:内网地图痛点

在政务、园区、工厂、军工等严格内网隔离的项目中,前端项目无法直接访问外网高德域名:

  • webapi.amap.com
  • jsapi-data1.amap.com
  • webst01.is.autonavi.com(卫星瓦片)

浏览器直接加载高德SDK会出现:跨域、混合内容、外网拦截、地图白屏、瓦片加载失败

高德官方并未提供私有化离线部署包,因此行业通用解决方案只有两种:

  1. 后端代理:Node + Express 中转请求、批量替换域名(本人开源实现)
  2. 前端拦截:Service Worker 劫持浏览器请求,本地改写域名

本文结合真实踩坑经验,深度对比两套方案,附带开源代码、原理、优缺点、适用场景。

开源仓库https://github.com/akcshen/gaode-proxy.git

技术栈:Node.js + Express + Axios、响应流批量替换、二进制透传

二、方案一:Node+Express 后端反向代理(生产主推)

2.1 方案原理

搭建一台内网 Node 代理服务,浏览器只访问内网代理地址,由服务端向外网请求高德资源,并且对返回内容做全局域名替换

核心流程:

  1. 前端引入 http://内网ip:3000/amapproxy/maps 加载SDK;
  2. Node 服务请求官方高德SDK;
  3. 对 JS、JSON、文本类响应批量替换域名为内网代理地址;
  4. 对 PBF、PNG 瓦片二进制资源原样透传,不做编码转换;
  5. 浏览器拿到改写后的SDK,后续瓦片、接口全部走内网代理。

2.2 核心能力(开源项目能力)

能力说明
SDK入口代理/amapproxy/maps 代理高德 JS SDK
Loca可视化代理支持 Loca 三维SDK转发
通用资源转发自动转发各类 amap.com 子域名
卫星瓦片代理适配 is.autonavi.com 卫星、路网瓦片
智能内容改写JS/JSON/URL 域名批量替换,二进制不处理
安全限制限制合法子域名,防止开放代理滥用

2.3 关键技术难点(本人真实踩坑)

难点1:https 域名嵌套改写困难

高德SDK内部存在大量硬编码HTTPS域名、转义域名、模板域名

  • 明文:https://webapi.amap.com
  • 转义:https:\/\/webapi.amap.com
  • 模板:{webst01,webst02}.is.autonavi.com

普通正则只能改明文,很多加密、分段、压缩后的HTTPS域名目前无法完全匹配,导致少量瓦片依然请求外网。

难点2:二进制资源不能乱改

瓦片图片、矢量PBF如果转成字符串替换,会直接损坏二进制编码,出现瓦片花屏、解析失败。

解决方案:区分响应类型,文本类替换、二进制类直透

难点3:协议错乱(http/https混合)

内网是http,外网SDK写死https,改写不当会出现:

  • 混合内容报错
  • 接口400/403
  • 瓦片跨域

项目提供 PUBLIC_BASEPUBLIC_SCHEME 强制修正协议头。

2.4 优点 & 缺点

✅ 优点

  • 前端零改动:代码不用改,只换SDK引入地址;
  • 兼容性最强:IE、老旧浏览器全部支持;
  • 统一管控:所有地图流量经过代理,方便防火墙管控;
  • 支持缓存:可加内存缓存/Nginx缓存,加速瓦片加载。

❌ 缺点

  • 存在少量深层加密HTTPS域名无法改写(目前遗留问题);
  • 需要额外部署一台Node服务;
  • 高并发下性能弱于Nginx。

三、方案二:Service Worker 前端请求拦截

3.1 方案原理

不搭建后端服务,纯前端技术。利用浏览器 ServiceWorker(SW) 拦截当前页面所有网络请求。

流程:

  1. 注册SW脚本,后台常驻;
  2. 监听所有 fetch 请求;
  3. 匹配高德域名,劫持请求;
  4. 改写请求Path、Header,转发到内网代理;
  5. 返回篡改后的响应给页面。

3.2 优势

  • 无需后端服务,纯前端实现;
  • 拦截粒度更细,能拦截JS内部动态生成的请求;
  • 不需要大量正则替换文本,直接拦截网络层;
  • 完美解决深层加密HTTPS域名无法替换的问题。

3.3 致命缺点(生产大坑)

  • 必须HTTPS环境:ServiceWorker 不允许纯http内网使用;
  • 不兼容老旧浏览器:IE彻底报废;
  • 注册、更新、缓存机制诡异,经常拦截失效;
  • 多标签页、刷新、离线状态容易BUG;
  • 复杂SDK内部WebWorker发起的请求,SW拦截不到。

四、两套方案横向对比(总结干货)

对比项Node Express 代理Service Worker 前端拦截
部署难度中等(部署Node服务)简单(纯前端)
浏览器兼容性极佳(兼容IE)差(必须HTTPS、现代浏览器)
域名改写能力大部分改写,少量加密HTTPS漏改极强,网络层直接拦截
稳定性高,适合长期生产一般,缓存、刷新容易失效
运维成本需维护Node进程无需服务端
推荐场景政务内网、老旧系统、生产环境现代内网、仅测试、临时方案

五、目前最优落地组合方案

结合我实际开发踩坑,生产环境推荐组合使用

  1. 主方案:Node.js 代理服务(稳定、兼容、简单);
  2. 补充方案:少量漏改的HTTPS域名,用 ServiceWorker 兜底拦截;
  3. 前置优化:外层套 Nginx 做负载、缓存、HTTPS证书终结。

六、开源项目使用教程

仓库地址:https://github.com/akcshen/gaode-proxy.git

6.1 快速启动

bash
npm install
npm start

6.2 内网前端引入方式

html
<script src="http://127.0.0.1:3000/amapproxy/maps?v=2.0&key=你的Key"></script>

6.3 环境变量常用配置

bash
PORT=3000
PUBLIC_BASE=http://192.168.x.x:3000
ACCESS_LOG=true

七、总结与后续优化方向

7.1 总结

高德内网代理没有完美方案,目前行业两种主流手段各有优劣:

  • Node反向代理:稳重、工程化、适合生产,唯一缺点是少量加密HTTPS域名无法改写;
  • ServiceWorker:拦截强、不用部署服务,但是浏览器限制太多、稳定性差。

7.2 后续优化计划

  1. 增强正则,补齐加密HTTPS域名改写规则;
  2. 增加内存缓存,提升瓦片加载速度;
  3. 集成SW兜底拦截,解决漏改请求;
  4. 支持Docker一键部署,降低内网部署成本。

八、开源地址

高德地图内网代理(Node.js)

GitHub:https://github.com/akcshen/gaode-proxy.git

欢迎Star、提Issue、共同完善内网地图代理方案。

最近更新