ArcGIS API For Javascript :如何解决跨网不能正常获取依赖项的问题?
一、前言
政企项目通常会在自组网以及保密网运行,有些单位甚至会有两个物理隔绝的网络存在。通常情况下我们会在两个网络中部署相同的地图服务和依赖项。但是也有其中一个网络密级很高没有服务器资源,不能单独部署依赖项的情况出现。
二、案例与原因初探
例如:现有 A、B 两张物理隔绝的网络。其中 A 网部署地图服务与依赖项, B 网密级很高,只进不出,且无法部署依赖项。
我们首先采用的是在前置机 C(双网卡,与 A 双向通信,与 B 单向通信)搭建转发服务,在此过程中就会出现依赖项加载失败的情况。根据对控制台网络请求查看,请求的 js 资源 IP 为 B 网配置项中的 IP 段,说明 A 网中依赖项中的 init.js 和 dojo.js 中配置写死,造成 B 通过 C 无法正常请求到相关资源。
三、解决方案
核心是使 init.js 和 dojo.js 动态获取主机 IP 更新配置项。基于此思路,我们进行了以下尝试:
1. 配置项 使用相对路径 —— 失败
2. 配置项 A 网代理 A 网(使用 ArcGIS 代理 + 原始 IP 端口 拼接路径) —— 失败
3. 配置项 使用 B 网配置 IP 端口 —— 失败
4. 配置项 C 机代理 A 网(使用前置机转发 + 原始 IP 端口 拼接路径)——失败
5. 配置项 C 机代理 B 网(使用前置机转发 + B 网配置 IP 端口 拼接路径)——失败
6. 配置项 获取当前请求的服务 IP 端口,更新至到配置项 —— 成功 10%
6.1 遇到的问题及解决思路
根据自动获取当前服务 IP 端口,在 B 网中可以正常调用 init.js ,但是 zh-cn.js 未能正常加载,说明在加载相关基础 js 时会重新拼接路径,而此时所获取的 baseurl 并非我们在头部修改的当前服务 IP 端口。
因此需要在源码中找到相对应拼接路径的位置,将其强行修改与头部的 baseurl 保持一致。
6.2 解决过程
6.2.1 获取当前服务 IP 端口
(function(exports) {
var doc = exports.document
, a = {}
, expose = +new Date()
, rExtractUri = /((?:http|https|file):\/\/.*?\/[^:]+)(?::\d+)?:\d+/
, isLtIE8 = ('' + doc.querySelector).indexOf('[native code]') === -1;
exports.getCurrAbsPath = function() {
// FF,Chrome
if (doc.currentScript) {
return doc.currentScript.src;
}
var stack;
try {
a.b();
} catch (e) {
stack = e.fileName || e.sourceURL || e.stack || e.stacktrace;
}
// IE10
if (stack) {
var absPath = rExtractUri.exec(stack)[1];
if (absPath) {
return absPath;
}
}
// IE5-9
for (var scripts = doc.scripts, i = scripts.length - 1, script; script = scripts[i--]; ) {
if (script.className !== expose && script.readyState === 'interactive') {
script.className = expose;
// if less than ie 8, must get abs path by getAttribute(src, 4)
return isLtIE8 ? script.getAttribute('src', 4) : script.src;
}
}
}();
}(window));
6.2.2 配置 baseUrl
将上述代码插入 init.js 最上部分,然后搜索 [HOSTNAME_AND_PATH_TO_JSAPI] ,将其更换为 getCurrAbsPath.replace("/"+getCurrAbsPath.split("/").pop(),"") + "/dojo" 。
6.2.3 找到二次拼接位置
根据 zh-cn 检索,找到以下位置。
"*now": function(q) {
q(['dojo/i18n!*preload*esri/nls/jsapi*["ar","az","ca","cs","da","de-de","el","en-gb","en-us","es-es","fi-fi","fr-fr","he-il","hu","it-it","ja-jp","ko-kr","nl-nl","nb","pl","pt-br","pt-pt","ro","ru","sk","sl","sv","th","tr","zh-tw","zh-cn","ROOT"]'])
},
在这里打断点,逐行执行,找到拼接处。
Wa = function(a, b, g, d, r, q, h, k, f, x) {
var t, y, w, m;
m = /^\./.test(a);
if (/(^\/)|(\:)|(\.js$)/.test(a) || m && !b)
return wa(0, a, 0, a);
a = Va(m ? b.mid + "/../" + a : a);
if (/^\./.test(a))
throw c("irrationalPath", a);
x || m || !q.star || (w = Aa(a, q.star[1]));
!w && b && (w = (w = Aa(b.mid, q)) && Aa(a, w[1]));
w && (a = w[1] + a.substring(w[3]));
b = (na = a.match(/^([^\/]+)(\/(.+))?$/)) ? na[1] : "";
(t = g[b]) ? a = b + "/" + (y = na[3] || t.main) : b = "";
var p = 0;
e(k, function(b) {
var c = a.match(b[0]);
c && 0 < c.length && (p = l(b[1]) ? a.replace(b[0], b[1]) : b[1])
});
if (p)
return Wa(p, 0, g, d, r, q, h, k, f);
if (g = d[a])
return f ? wa(g.pid, g.mid, g.pack, g.url) : d[a];
d = (w = Aa(a, h)) ? w[1] + a.substring(w[3]) : b ? ("/" === t.location.slice(-1) ? t.location.slice(0, -1) : t.location) + "/" + y : v("config-tlmSiblingOfDojo") ? "../" + a : a;
debugger
/(^\/)|(\:)/.test(d) || (d = r + d);
console.log(wa(b, a, t, Va(d + ".js")))
return wa(b, a, t, Va(d + ".js"))
}
发现 /(^\/)|(\:)/.test(d) || (d = r + d); 是拼接语句,r 是问题关键。我们只需要在 debugger 处将 r 重新赋值即可。
r=getCurrAbsPath.replace("/" + getCurrAbsPath.split("/").pop(), "") + "/dojo/";
6.3 测试
B 网成功地向 C 前置机转发服务请求,获得了 A 网的地图依赖项和地图服务。至此问题解决。
四、总结
以上就是困扰了很久的跨网未能正常获取地图资源的问题的解决过程与解决方法。
ArcGIS API For Javascript :如何解决跨网不能正常获取依赖项的问题?的更多相关文章
- arcgis api for JavaScript _跨域请求
arcgis api for JavaScript 中出现跨域请求是常见问题, 通常出现类似如下错误消息类似: XMLHttpRequest cannot load http://10.32.2.7 ...
- ArcGIS API for javascript开发笔记(二)——解决ArcGIS Service中的服务在内网环境下无法进行javascript预览问题
感谢一路走来默默支持和陪伴的你~~~ ----------------------------拒绝转载-------------------------------- 1.问题说明 在使用ArcGIS ...
- ArcGIS API for JavaScript 4.x 本地部署之跨域问题解决法:CORS
众所周知,在离线部署ArcGIS API for JavaScript时,有时候会产生微件上的字体.符号变成方框的问题.这是遇到了跨域,只需要对所在服务器进行配置即可. 本篇使用的环境是:API配置在 ...
- ArcGIS API for JavaScript 4.2学习笔记[5] 官方API大章节概述与内容转译
内容如上,截图自ESRI官网,连接:ArcGIS API for JavaScript 4.2 [Get Started] 类似于绪论一样的东西,抽取了最需要关注的几个例子.如:加载Map和View, ...
- 【1】ArcGIS API for JavaScript 4.5/4.6 本地部署
惭愧,和我的学弟比起来,我所开始接触前端开发,ArcGIS API for JavaScript的时间和深度远远不及于他. 一年之尾,亦是一年之始,我也将正式开始我的博客生涯.本人在校学习并且做项目, ...
- ArcGIS API for Javascript 使用缓冲区结果做query查询出现“esri.config.defaults.io.proxyUrl 尚未进行设置”错误
1.前言 在研究ArcGIS API for JavaScript时会遇到这样的问题,比如我们在做缓冲区分析时,用分析的范围作为空间查询query的参数,在执行结果中总是会看到“esri.config ...
- Arcgis api for javascript学习笔记(4.5版本) - 本地部署及代理配置
在开发过程中,由于api的文件比较多,没必要每个项目都将api加入到解决方案中.况且在VS中如果将api加入解决方案,在编写css或js代码时,由于智能提示需要扫描脚本等文件,会导致VS很卡.所以个人 ...
- 基于ArcGIS API for Javascript的地图编辑工具
最近工作上需要用ArcGIS API for Javascript来开发一个浏览器上使用的地图编辑工具,分享一下一些相关的开发经验. 我开发的地图编辑工具是根据ESRI提供的例子修改而来的,参考的例子 ...
- arcgis api for javascript 3.16开发(一)
原来一直都在用Flex开发arcgis的地图接口,用的时间很长,用的习惯也顺手,可Flex这个开发工具已经基本要淘汰了,并且地图借助flash的方式加载在浏览器里已经不能适应webgis的快速开发需求 ...
随机推荐
- opencv::像素重映射
像素重映射(cv::remap) 简单点说就是把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去,形成一张新的图像. Remap( InputArray src, // 输入图像 Ou ...
- QuartzCode快速开发动画代码工具
QuartzCode快速开发动画代码工具 QuartzCode一款快速,轻量,强大的动画工具,可快速得到原生的ObjC/Siwft代码 我可以用QuartzCode做什么? 应用程序演练动画 动画菜单 ...
- JAVA学习笔记-1.Tomcat&Servlet
##web相关概念 1.软件架构 1.C/S 2.B/S 2.资源分类 1.静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源, 静态资源可以直接被浏览器解析. * 如:html, css, ...
- nginx 前后端分离 代理转发,解决跨域问题
场景 适用于公司有前端,项目采用前后端分离.类似于我们 后端 springboot 提供接口,前端专门写html调用相应的接口,解决跨域问题 配置说明 worker_processes 1; even ...
- 查看线上日志利器less
less实用命令 搜索 很多关于命令的解释有点令人困惑,因为前字,forward是向前,before也是前面. 上表示backward 下表示forward 向下搜索 / - 使用一个模式进行搜索,并 ...
- python *args,**kwargs参数
实际上,关键的是*和** 我们以三个例子来解释: 普通的使用参数: def test1(arg): print(arg) test1("a") 输出: a *是将剩下的参数用元祖表 ...
- Apache Solr Velocity模板注入RCE漏洞复现
Apache Solr Velocity模板注入RCE漏洞复现 一.Apache Solr介绍 Solr是一个独立的企业级搜索应用服务器,它对外提供类似于web-service的API接口,用户可以通 ...
- [Java] 生成二维码源码,可以在二维码中间加logo,底部可以加文字介绍
链接:https://pan.baidu.com/s/1bc1h-ix-No-2o9Ysd4_B3Q提取码:0ad4
- 学习笔记02form
1.<form>为表单标签*如果要把数据提交到服务器,则需要将<input> <textarea> <select>等表单元素放到<from> ...
- Python的闭包以及迭代器
一,闭包 什么是闭包呢?闭包就是内层函数,对外层函数(非外层)的变量的引用,叫做闭包 def mz(): name = 'YJ' def xue(): print(name) #闭包 xue() mz ...