最近在升级华丹开发平台,想通过js直接获取上下文路径contextPath,而不用通过参数配置的方式,减少用户配置麻烦。
上网查了一下,没有理想的方案。比如(节选自网上资料):
方法一:
在JSP页面中写上这么一段代码:var $ctx = '<%=request.getContextPath()%>';
然后在下方加上其他JS文件的引用:
<script type="text/javascript">
var $ctx='<%=request.getContextPath()%>';
</script>
<script type="text/javascript" src="/res/admin/js/index.js"></script>
?$base?这个变量就能在其他JS文件中使用。
function c() {
a.attr("src", $ctx + "/admin/welcome.html");
}
方法二:
在被引用的js后面添加一个参数,将上下文路径传进去,然后在js代码中解析这个参数,得到上下文路径:
<script src="mine.js?ctx=<%=request.getContextPath()%>" type="text/javascript"></script>
然后在mine.js中开头写上这么一句话:?
var js=document.scripts;
var url=js[js.length-1].src;
var $ctx=getQueryString(url,'ctx');
function getQueryString(url,name){
var reg = new RegExp("(\\?|&)"+ name +"=([^&]*)(&|$)");
var r = url.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
这里面一个非常重要的一点在于,如果页面中有很多js引用,而mine.js无论插在开头还是末尾亦或中间,var url=js[js.length-1].src;这一行代码都能获取到mine.js自身的url,这样var ctx=$ctx;这一行代码都能获取到mine.js自身的$ctx。?
这其中的原因大致就是JS从上到下解释执行模式所带来的一个小福利了。
方法三:
使用 / 直接对url进行解析
function getContextPath(){
var pathName = document.location.pathname;
var index = pathName.substr(1).indexOf("/");
var result = pathName.substr(0,index+1);
return result;
}
或者
//js获取项目根路径,如: http://localhost:8083/uimcardprj
function getRootPath(){
//获取当前网址,如: http://localhost:8083/uimcardprj/share/meun.jsp
var curWwwPath=window.document.location.href;
//获取主机地址之后的目录,如: uimcardprj/share/meun.jsp
var pathName=window.document.location.pathname;
var pos=curWwwPath.indexOf(pathName);
//获取主机地址,如: http://localhost:8083
var localhostPaht=curWwwPath.substring(0,pos);
//获取带"/"的项目名,如:/uimcardprj
var projectName=pathName.substring(0,pathName.substr(1).indexOf('/')+1);
return(localhostPaht+projectName);
}
这两段代码大同小异,都是用 /?对url进行分割,然后获取域名之后的第一个路径。这样做有个问题,如果上下文路径是 /?或者多层路径,那解析出来的就是错误的,所以不推荐使用。
上述方案均不太理想,今天在阅读layui源码时,突然来了灵感,有了一个完美的方案:
选一个js文件提供获取contextPath,比如在华丹快速开发平台主js文件charisma.js。
对于这个文件的相对路径我们是明确的,比如:/charisma/system/static/js/charisma.js
那么我们想办法获取到完整路径,形如:
http://127.0.0.1:8088/charisma/charisma/system/static/js/charisma.js
解析这个路径,取第一个/开头,相对路径(不包括)/charisma/system结尾的,就是项目的根路径contextPath了。
直接附上源码:
//定义为类的成员变量,构造函数中直接赋值,不能定义为成员方法,如Charisma.prototype.contextPath=function()...,这样运行时就脱离了该js环境,取不到对应的值。
this.contextPath = function() {
var jsPath = document.currentScript ? document.currentScript.src : function() {
var js = document.scripts,
last = js.length - 1,
src;
for (var i = last; i > 0; i--) {
if (js[i].readyState === 'interactive') {
src = js[i].src;
break;
}
}
return src || js[last].src;
};
//以上得到当前js文件的完速路径,形如:
//http://127.0.0.1:8088/charisma/charisma/system/static/js/charisma.js
var arr=jsPath.replace(/\/{2}/,'').match(/\/.*(?=\/charisma\/system)/i);
return arr?arr[0]:"";
};