主题
超链接不就是一个地址字符串吗?这能有什么花头? LZSB! 曾经我也是这么想的....
最近对apache的学习让我对网页中超链接,CSS,js的路径的写法有了一些新的认识.
所以这篇文章主要分享一下我的一些想法与发现..
相对路径
最早以前我用的就是相对路径,刚开始感觉用起来很爽...很简单...比如当前路径是localhost:8080/projectName/a.jsp 我想超链接到localhost:8080/projectName/b.jsp 我只需要写<a href="b.jsp">b.jsp</a>就可以了..但是很快我发现了一个问题...如果一个视图有多个映射地址..比如localhost:8080/projectName/a.jsp 和 localhost:8080/projectName/path1/path2 映射到的是同一个jsp...那里面的超链接是肯定会有问题的.
因为路径层次都变了...这种情况是可能会发生的,因为会有服务器跳转的存在,所以一个view可能会对应N个URL..而每个URL不同,根据相对路径去找资源,拼接得到资源的URL是肯定不同的..所以这个方法并不好,除非保证一个view只对应一个URL.
绝对路径
因为相对路径不太好,所以我开始使用绝对路径...使用绝对路径可以避免上述相对路径遇到的问题..
我一般是这么使用的...
1.先写一个每个页面head里都会导入的jsp.在这个jsp里面:
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%> <!-- basePath -->
<base href="<%=basePath%>">
2.在每个jsp中要引用其他URL的资源的时候直接<link href="resources/css/index2.css" rel="stylesheet" />
解释和小结:
使用<base>这个标签以后浏览器会把所有相对路径资源前面拼接base标签里面的href值得到完整的URL路径.不写这个标签直接使用相对路径的时候相当于base的href就是当前URL的上一级.
像我这样写以后index2.css的完整URL就是 IP:端口/上下文/resources/css/index2.css
上下文就是项目部署的上下文环境的值,可以在tomcat的server.xml里面context节点里的path里去设置..
开发的时候eclipse部署到tomcat默认上下文环境的值是项目名称.所以项目首页是localhost:8080/项目名称
而项目上线以后直接映射到域名,比如www.test.com那这个上下文环境的值是/
虽然上下文环境变了.但是通过<%=basePath%>可以过滤掉这个细节,保证资源的URL是从IP写起的,一定找得到这个资源..
改进版的相对路径
绝对路径的方法我一直用了好久,觉得还是蛮好用的,无论环境怎么变,链接URL都不用变..直到我学习了apache的反向代理...
使用绝对路径的问题在于如果使用了反向代理,比如把www.a.com ProxyPass到了内网IP192.168.X.X...因为apache只是一个空壳,项目并没有部署在apache上.真正的项目部署在192.168.X.X那台tomcat上,所以项目里的jsp里的basePath计算出来的href是192.168.X.X:端口/上下文,而不是www.a.com
这个时候如果你点了www.a.com对应的jsp上面的超链接的话,会跳转到192.168.X.X:端口/上下文/超链接相对路径...就是说浏览器地址栏从www.a.com变成了192.168.X.X/....
这样的话相当于apache的反向代理是没法发挥作用的,因为你的资源写的是绝对路径...apache并不知道这个地址是需要代理的...它也没有办法去管理,因为它不会去搜索你返回的html并把连接一个一个替换掉..
这个时候仍然需要使用相对路径,但是我们可以从根地址写起...
具体做法:
1.删掉<base>标签
2.每个链接从根目录写起,用jstl的c标签,比如<c:url value="/js/jquery.js"/>
解释和小结:
c:url标签会自动计算出上下文环境...所以<c:url value="/js/jquery.js"/>得到的值是/上下文环境/js/jquery.js
这样的话即使上下文环境变了,也能得到正确的值.因为得到的值是从根目录写起的/开头的.所以浏览器会把这个值拼接在IP:端口后面,所以浏览器最终计算得到的jquery.js的值是IP:端口/上下文环境/js/jquery.js
这个值和上述使用绝对路径得到的值是一样的,只是使用绝对路径需要从IP写起,最终路径不需要浏览器计算,直接就能得到,不依赖于当前浏览器地址栏的地址..这里这种相对路径是从/上下文环境 写起(上下文环境由c:url计算得出),最终路径需要浏览器拼接IP和端口计算得到,所以依赖于当前浏览器地址栏的地址.
所以在反向代理的时候拼接的IP和端口是apache服务器上的地址和端口,然后又会被apache正确ProxyPass到内网tomcat上..
当然,使用base标签也是可以的,<base href="<c:url value="/" /> ">这样就不需要在每个URL前面都使用c:url标签了...
总结
就目前我的经验来看可能使用c:url标签 写资源路径是最佳的方法了...既可以屏蔽上下文变动带来的URL路径变化的影响,又可以正确使用反向代理,得到正确的代理路径...
不过c:url只能在jsp中使用,不知道纯html页面怎么办...
说不定以后会有其他理解....