最近在升级华丹开发平台,想通过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]:"";

 };