前言

目前国内市场就三大地图:高德地图、百度地图、腾讯地图,但是这些地图都是面向公网的,而针对于一些特殊情况下,比如客户需要访问地图的相关服务,但是是在公司的内网访问,内网又不支持访问公网,这就感觉到这些地图瓶颈了,于是就费尽脑汁地想在内网部署一套完整的地图系统,可惜了,这三大地图很多都是基于接口的服务的,无法在内网独立建设一套地图。

虽然当前在公网环境可以方便的获取到免费GIS服务,但有些项目因为处于专网环境,客户不允许电脑访问公网,导致必须要在专网环境花费较多成本自建GIS服务。

对于预算有限的项目,我们是否有简单的方法实现专网客户使用公网免费GIS服务呢?下面一步步分析,通过可以访问公网的代理服务器来实现专网电脑访问高德GIS服务。

实现步骤

  1. 我们将高德地图demo部署到我们nginx服务中,浏览器端打开此页面即能访问到高德地图。

  2. 浏览器访问高德地图demo,按F12,发现首先会通过此接口获取js api文件,src=“https://webapi.amap.com/maps?v=1.4.15&key=您申请的key”。(key申请方法

  3. 专网浏览器端为了获取js api文件,可以通过代理服务器来访问。在nginx代理服务器中增加如下配置即可。

    1
    2
    3
    location /maps {
    proxy_pass https://webapi.amap.com/maps;
    }
  4. 修改高德地图demo html文件,将src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key修改为src="http://代理服务器ip/maps?v=1.4.15&key=您申请的key。【代理服务器默认使用80端口】

  5. 浏览器再次访问高德地图demo,按F12,发现js api文件已经能通过代理服务器访问到,追踪之后访问链接,发现地图服务会自调用如下这些地址对应的接口restapi.amap.comwebapi.amap.comvdata.amap.comwprd0{1-4}.is.autonavi.comwebrd0{1-4}.is.autonavi.com

  6. 为了使获取js api文件之后的访问都经过代理服务器,我们需要代理服务器返回js api文件时修改相应地址为代理服务器地址。为了实现此目的,nginx代理服务器需要添加 http_sub_module模块with-http_ssl_module模块ngx_http_substitutions_filter_module模块,重新编译nginx以生成新的bin文件,编译配置:

    1
    --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --add-module=/root/server/nginx_module/ngx_http_substitutions_filter_module

模块安装方法:

使用ngx_http_sub_module模块好处是nginx内置该模块使用方便,不足之处在于该模块不支持正则替换,灵活性不够,支持正则匹配替换的第三方模块ngx_http_substitutions_filter_module:

下载地址:https://github.com/yaoweibin/ngx_http_substitutions_filter_module/archive/master.zip

添加参数–add-module=/模块解压后文件路径

编译安装nginx,注意加上–with-http_sub_module模块,这里提供编译的参数:

1
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_sub_module --add-module=/root/server/nginx_module/ngx_http_substitutions_filter_module
  1. nginx代理配置增加如下内容用于替换地址为代理服务器地址:

    1
    2
    3
    4
    5
    6
    7
    8
    location /maps {
    proxy_set_header Accept-Encoding "";
    proxy_pass https://webapi.amap.com/maps;
    sub_filter_types *;
    sub_filter_once off;
    sub_filter 'http://webapi.amap.com' 'http://代理服务器ip/webapi';
    #第5部分列出的地址都要做替换,此处只给出一个例子
    }

    说明如下:

    proxy_set_header Accept-Encoding “”; #返回的js api文件不压缩,以便替换其中内容;
    sub_filter_types *; #所有文件类型
    sub_filter_once off; #所有匹配到的都替换
    sub_filter ‘http://webapi.amap.com‘ ‘http://代理服务器ip/webapi’; #中间为被替换内容(即js文件中原始地址),后面为替换后内容(即内网代理服务器地址)

  2. 断开电脑公网访问权限,浏览器再次访问高德地图demo,按F12,发现已经能够正常展示地图。但还有两个图标集文件无法访问,分别为http://vdata.amap.com/style_icon/icon-normal-small.png
    http://vdata.amap.com/style_icon/icon-biz-small.png,暂时没找到访问这两个图标集的源头,通过修改本机hosts文件采用代理方式来访问(hosts文件增加配置:代理服务器ip vdata.amap.com),nginx增加如下代理配置

1
2
3
location /style_icon/ {
proxy_pass http://vdata.amap.com/style_icon/;
}

高德配置内网nginx代理完整配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
server {
listen 80;
server_name localhost;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
location /restapi/ {
proxy_pass https://restapi.amap.com/;
}
location /webapi/ {
proxy_pass https://webapi.amap.com/;
}
location /vdata/ {
proxy_pass https://vdata.amap.com/;
}
location /wprd01/ {
proxy_pass https://wprd01.is.autonavi.com/;
}
location /wprd02/ {
proxy_pass https://wprd02.is.autonavi.com/;
}
location /wprd03/ {
proxy_pass https://wprd03.is.autonavi.com/;
}
location /wprd04/ {
proxy_pass https://wprd04.is.autonavi.com/;
}
location /webrd01/ {
proxy_pass https://webrd01.is.autonavi.com/;
}
location /webrd02/ {
proxy_pass https://webrd02.is.autonavi.com/;
}
location /webrd03/ {
proxy_pass https://webrd03.is.autonavi.com/;
}
location /webrd04/ {
proxy_pass https://webrd04.is.autonavi.com/;
}
location /style_icon/ {
proxy_pass http://vdata.amap.com/style_icon/;
}
location /jsapi_demos/ {
proxy_pass http://a.amap.com/jsapi_demos/;
}
location /ui/ {
proxy_pass http://webapi.amap.com/ui/;
}
#代理获取js api文件并修改文件内容
location /maps {
proxy_set_header Accept-Encoding "";
proxy_pass https://webapi.amap.com/maps;
sub_filter_types *;
sub_filter_once off;
sub_filter 'http://webapi.amap.com' 'http://192.168.0.181:9098/webapi';
sub_filter 'https://webapi.amap.com' 'http://192.168.0.181:9098/webapi';
sub_filter 'http://restapi.amap.com' 'http://192.168.0.181:9098/restapi';
sub_filter 'http://vdata.amap.com' 'http://192.168.0.181:9098/vdata';
sub_filter 'vdata.amap.com' '192.168.0.181:9098/vdata';
sub_filter 'webapi.amap.com/count' '192.168.0.181:9098/webapi/count';
sub_filter 'wprd0{1,2,3,4}.is.autonavi.com' '192.168.0.181:9098/wprd0{1,2,3,4}';
sub_filter 'webapi.amap.com/theme' '192.168.0.181:9098/webapi/theme';
sub_filter 'restapi.amap.com/v4' '192.168.0.181:9098/restapi/v4';
sub_filter 'webapi.amap.com/style' '192.168.0.181:9098/webapi/style';
}
}