资讯动态

ArcGIS JS 3.3.9 SDK离线部署与性能优化实战

发布时间:2026/10/17 4:59:20 来源:尧图企业网站定制
简介ArcGIS JavaScript API 3.39 SDK 是 Esri 面向 Web GIS 开发者推出的地图开发工具包适合具备一定 JavaScript 基础、希望构建交互式地理信息应用的前端与 GIS 从业者。它围绕地图与图层、几何对象与空间分析、地理编码与几何服务、控件与事件交互、符号化样式、数据动态加载、分级渲染与响应式设计、OAuth 2.0 与 Token 授权等模块展开可支撑从底图叠加、缓冲区分析到服务调用的完整开发链路。资源包共约 2000 个文件以 1522 个 html 示例页面、972 个 png 图片、253 个 css 样式、141 个 js 脚本为主另含 json、csv、psd、字体与少量 pdf 等素材压缩包约 85.19MB目录结构便于按功能模块检索。目前已有 144 人学习下载。借助其中的示例页面与样式资源读者可快速理解 API 调用方式、图层组织与界面控件配置对照实现地图展示、空间查询与可视化效果是上手 ArcGIS JS API 3.39 的实用参考。1. 一个老版本 SDK 压缩包为什么还有人专门去找如果你在搜索框里敲下arcgis_js_v339_sdk.zip大概率不是出于好奇而是被某个跑了很多年的业务系统卡住了。这套 3.3.9 版本的 ArcGIS API for JavaScript 属于 3.x 时代的晚期版本官方早已停止功能更新但大量存量 GIS 项目仍然挂在它上面内网环境不能随便升级、老代码里全是dojo.require、地图服务依赖esri/layers/ArcGISDynamicMapServiceLayer这类 3.x 专有模块。你拿到这个 zip本质上是拿到一份离线可用的开发包里面通常包含 API 主文件、Dojo 依赖、样式表、图标资源和本地文档。它解决的核心问题只有一个在没有外网、不能走 CDN 的环境里让 3.x 地图应用继续跑起来。适合谁维护存量 GIS 系统的一线开发、需要在内网做离线部署的运维、以及被要求「先别动架构把功能补上」的接盘同学。2. 解压之后先别急着写代码目录结构与本地部署方式很多人拿到压缩包第一反应是双击 index.html结果白屏或者一堆 404。3.x 的 SDK 不是「打开就能用」的静态站点它依赖一套固定的目录约定和 Dojo 的模块加载机制。先把结构看清楚再决定用哪种方式挂到项目里。2.1 压缩包里到底有什么解压后典型结构如下不同打包方式可能略有差异但核心目录一致目录/文件作用是否必须arcgis_js_api/library/3.39/API 主目录含init.js、dojo/、dijit/、dojox/必须arcgis_js_api/library/3.39/esri/Esri 专有模块如map、layers、tasks必须arcgis_js_api/library/3.39/esri/css/esri.css地图控件、弹窗、比例尺等样式必须arcgis_js_api/library/3.39/esri/themes/主题样式常用light或dark按需arcgis_js_api/library/3.39/esri/images/缩放按钮、定位图标等图片资源必须arcgis_js_api/library/3.39/jimu.js等部分定制包会带标准 SDK 不一定有按需关键点init.js和dojo/dojo.js是入口esri/下的模块通过 Dojo AMD 加载器按需拉取。你不需要手动引入每一个 js但必须保证dojoConfig里的baseUrl指向正确位置。2.2 三种本地挂载方式选哪种看你的服务器方式一直接放到 Web 服务器静态目录。这是最稳的做法。把library/3.39/整个目录拷到 Nginx 或 IIS 的静态资源路径下比如/static/arcgis_js_api/library/3.39/。然后页面里这样写!DOCTYPE html html head meta charsetutf-8 title本地 3.3.9 地图/title link relstylesheet href/static/arcgis_js_api/library/3.39/esri/css/esri.css style html, body, #mapDiv { margin: 0; padding: 0; height: 100%; } /style script // 关键告诉 Dojo 去哪里找 Esri 模块 var dojoConfig { parseOnLoad: true, baseUrl: /static/arcgis_js_api/library/3.39/, packages: [ { name: esri, location: esri }, { name: dojo, location: dojo }, { name: dijit, location: dijit }, { name: dojox, location: dojox } ] }; /script script src/static/arcgis_js_api/library/3.39/init.js/script script require([ esri/map, esri/layers/ArcGISTiledMapServiceLayer, dojo/domReady! ], function(Map, TiledLayer) { var map new Map(mapDiv, { center: [116.39, 39.9], // 示例坐标按实际业务改 zoom: 10, basemap: topo // 离线环境建议换成自己的切片服务 }); var layer new TiledLayer(http://内网服务地址/arcgis/rest/services/底图/MapServer); map.addLayer(layer); }); /script /head body div idmapDiv/div /body /html逻辑说明dojoConfig必须在init.js之前定义否则加载器不知道esri包在哪。baseUrl末尾要带斜杠packages里的location是相对baseUrl的路径。parseOnLoad让>require([ esri/map, dojo/domReady! ], function(Map) { // 回调里 Map 才可用 var map new Map(mapDiv, { center: [-118.24, 34.05], zoom: 8, logo: false, // 隐藏 Esri logo内网项目常关 showAttribution: false }); // 地图加载完成事件图层操作建议放这里 map.on(load, function() { console.log(地图底图加载完成); }); });参数说明center是[经度, 纬度]注意不是[lat, lng]。zoom是初始级别3.x 支持小数级别但切片服务通常按整数取图。logo和showAttribution在离线内网可以关但如果你用的是有版权的底图服务建议保留 attribution。3.2 动态图层与切片图层的选型差异3.x 里最常用的两个图层类是ArcGISDynamicMapServiceLayer动态和ArcGISTiledMapServiceLayer切片。动态图层每次请求由服务端实时渲染支持图层定义、时间过滤但出图慢切片图层走缓存快但样式固定。选型看业务如果只是展示底图用切片如果需要按权限过滤图层、动态改符号用动态。require([ esri/map, esri/layers/ArcGISDynamicMapServiceLayer, esri/layers/ArcGISTiledMapServiceLayer, dojo/domReady! ], function(Map, DynamicLayer, TiledLayer) { var map new Map(mapDiv, { center: [121.47, 31.23], zoom: 11 }); // 切片底图快 var baseLayer new TiledLayer(http://内网/arcgis/rest/services/BaseMap/MapServer); map.addLayer(baseLayer); // 动态业务图层可控制子图层显隐 var dynLayer new DynamicLayer(http://内网/arcgis/rest/services/Business/MapServer); // 只显示第 0、2 个子图层 dynLayer.setVisibleLayers([0, 2]); // 设置图层定义相当于服务端过滤 dynLayer.setLayerDefinitions([11, STATUS ACTIVE]); map.addLayer(dynLayer); });逻辑说明setVisibleLayers接收子图层索引数组索引对应服务 REST 端点里的layers列表。setLayerDefinitions是字符串数组每个元素对应一个子图层的 where 子句顺序要和子图层索引对齐。这两个方法在动态图层上才有效切片图层不支持。3.3 点击查询与信息窗口的最小闭环地图不能只看还得能点。3.x 的map.on(click, ...)拿到的是屏幕坐标要转成地理坐标再发给查询任务。require([ esri/map, esri/tasks/QueryTask, esri/tasks/query, esri/InfoTemplate, dojo/domReady! ], function(Map, QueryTask, Query, InfoTemplate) { var map new Map(mapDiv, { center: [113.26, 23.13], zoom: 12 }); var queryTask new QueryTask(http://内网/arcgis/rest/services/POI/MapServer/0); map.on(click, function(e) { var query new Query(); query.geometry e.mapPoint; // 点击处的地理坐标 query.returnGeometry true; query.outFields [NAME, ADDRESS]; query.spatialRelationship Query.SPATIAL_REL_INTERSECTS; queryTask.execute(query, function(result) { if (result.features.length 0) return; var feature result.features[0]; map.infoWindow.setTitle(查询结果); map.infoWindow.setContent( 名称 feature.attributes.NAME br地址 feature.attributes.ADDRESS ); map.infoWindow.show(e.mapPoint); }); }); });参数说明spatialRelationship默认是SPATIAL_REL_INTERSECTS点查询通常够用。outFields不写会返回所有字段内网服务字段多时建议显式指定减少传输量。InfoTemplate可以用模板字符串自动渲染但字段名要和outFields一致否则显示undefined。4. 避坑与排查3.3.9 离线部署最容易翻车的五件事这一章全是血泪经验每条按「现象 → 原因 → 解决」写。你在内网环境踩的坑大概率逃不出这五类。4.1 地图白屏控制台报dojo is not defined现象页面打开后#mapDiv一片空白控制台第一行就是dojo is not defined或require is not defined。原因init.js没加载成功或者dojoConfig写在init.js之后。解决确认init.js的 Network 状态码是 200且dojoConfig脚本块在init.js之前。如果用了 CDN 回退逻辑检查回退路径是否指向本地。4.2 模块 404路径里多了一层或少了一层现象require([esri/map])报 404请求地址是/arcgis_js_api/library/3.39/esri/map.js但实际文件在esri/map.js下还有子目录。原因baseUrl配错或者packages里的location写成了绝对路径。解决baseUrl指向library/3.39/packages里esri的location写esri相对。用浏览器直接访问baseUrl esri/map.js看能不能打开打不开就是路径问题。4.3 中文标注乱码服务端返回的 JSON 编码不对现象地图上的中文标注显示成????或方块。原因ArcGIS Server 返回的 JSON 默认可能是UTF-8但你的页面meta charset写成了gb2312或者 Nginx 给.json加了错误的charset。解决页面统一UTF-8服务器响应头Content-Type: application/json; charsetutf-8。如果是动态图层出图乱码检查服务端字体是否支持中文。4.4 跨域请求被拦Access-Control-Allow-Origin缺失现象地图底图能出但查询任务报 CORS 错误。原因页面域名和 ArcGIS Server 域名不同且服务端没开 CORS。解决内网环境常见做法是把地图服务和页面放同一域名下用 Nginx 反代/arcgis到后端服务。如果必须跨域在 ArcGIS Server 的web.config或 Nginx 里加Access-Control-Allow-Origin。注意 3.x 的esri/request默认走 XHR不是 JSONP。4.5 升级到 4.x 后 API 全变回退成本要提前算现象有人建议「都什么年代了还用 3.x」你试着升到 4.x发现dojo没了、Map构造参数变了、图层类名全改。原因4.x 是全新架构基于 TypeScript 和 WebGL不兼容 3.x 的 AMD 写法。解决如果项目只是维护别轻易升。把 3.3.9 的 SDK 固化到内网静态资源锁死版本。真要升先评估esri/map、esri/layers、esri/tasks这三块的重写量通常不是小工程。提示内网部署时把整个library/3.39/目录打成压缩包备份并在 Nginx 配置里给.js和.css设置长缓存。3.x 的文件不会变缓存一年没问题。5. 让老版本跑得更稳离线资源裁剪与加载提速3.3.9 的完整包体积不小Dojo 全家桶加上 Esri 模块未压缩前可能几十 MB。内网带宽有限时首屏加载会明显变慢。这一章讲两个具体技巧按需裁剪和加载顺序优化。5.1 裁剪掉用不到的 Dojo 模块Dojo 的dojox/目录里很多模块你根本不用比如图表、编辑器、移动端控件。可以在部署前把dojox/下与地图无关的子目录删掉只保留dojox/gfx部分 Esri 符号依赖等必要项。但要注意Esri 的esri/模块之间有隐式依赖删之前用浏览器 Network 面板跑一遍完整业务流程看哪些dojox文件被实际请求了只保留这些。# 示例在 Linux 下查看某次页面加载实际请求了哪些 dojox 文件 # 假设你已经有访问日志过滤出 dojox 路径 grep -oE /dojox/[^]\.js access.log | sort -u # 如果日志不方便用 curl 模拟加载 init.js 后的依赖树不现实 # 更稳的做法浏览器开发者工具 - Network - 筛选 dojox逻辑说明不要凭感觉删。3.x 的模块加载是运行时的只有实际执行到某个功能才会拉对应文件。先跑全功能记录请求列表再对照裁剪。裁剪后必须回归测试尤其是打印、测量、编辑这些容易漏的模块。5.2 用dojoConfig的async和parseOnLoad控制节奏async: true是 3.x 推荐的异步加载模式但老代码里很多用同步dojo.require混用会出问题。如果你的代码全是require([...], callback)可以开async: true提升并行度。parseOnLoad如果页面没有>var dojoConfig { async: true, // 全异步加载推荐新代码 parseOnLoad: false, // 没有声明式控件就关掉 baseUrl: /static/arcgis_js_api/library/3.39/, packages: [ { name: esri, location: esri }, { name: dojo, location: dojo }, { name: dijit, location: dijit }, { name: dojox, location: dojox } ], // 开启缓存内网重复访问更快 cacheBust: false };参数说明cacheBust: false让 Dojo 不在 URL 后加时间戳配合服务器长缓存二次加载几乎秒开。但开发阶段建议设true避免改了代码浏览器不刷新。async: true下不能用dojo.require同步写法会直接报错。5.3 一个验证加载性能的笨办法在map.on(load)里打时间戳和performance.timing.navigationStart相减得到从页面开始到地图就绪的毫秒数。内网环境这个值通常在 800ms 到 2s 之间。如果超过 3s优先查是不是dojox被全量加载了或者某个图层服务响应慢。把esri.css和init.js放同一个域名下减少 DNS 查找也能省一两百毫秒。我自己的习惯是每次接手一个 3.x 老项目先不动业务代码只把 SDK 目录、dojoConfig、Nginx 缓存这三样理一遍往往首屏就能快一半。老版本不是不能用是很多人没把它当回事去调。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑