关于WEB-INF目录不提供外部访问及JSP引用 js,css 文件路径问题
在 web 项目开发过程中,我们常常使用到 JSP,以及对静态资源,js,css 等引用,但是我们应该把这些资源文件放在哪个目录下面咧,怎么引用。
当然如果是前后端分离的项目倒不用考虑这些。
WEB-INF:出于安全性的考虑,这个目录是禁止外部直接访问的,所以 JSP 页面放在这个目录及其子目录下面是起到保护作用的。
在 jsp 页面中少不了的是对 js,css 文件的引用,那么我们引用的时候又有两种方式:
1)相对路径:就是说相对于这个 jsp 页面位置,js,css 文件所在的位置,这种引用是相对的,当某一方位置发生变化是,这个相对路径就得跟着改变。
2)绝对路径:这是我们在开发中常用的,request.getcontextPath() 这是获取 web 项目上下文,也就是说 web 根目录 WebContent(WEB-INF 的上一级)
举个例子:
引用根目录下images的图片:
1
|
< img src = "/images/abc.jpg" /> |
引用同级目录images的图片:
1
|
< img src = "images/abc.jpg" /> 或 < img src = "./images/abc.jpg" /> |
引用上级目录下的子目录images的图片:
1
|
< img src = "../images/abc.jpg" /> |
引用上两级目录下的子目录images的图片:
1
|
< img src = "../../images/abc.jpg" /> |
在使用绝对路径的时候,这样子,对于整个项目是绝对的路径。
jsp 使用绝对路径引用 js,css 文件,同时 js,css 文件又放到了 WEB-INF 目录下面,这时候的引用是失败的,当我们在浏览器访问的时候,会出现找不到引用的 js,css 文件。
分析:
这个问题的原因正是由于 WEB-INF 拒绝外部直接访问, 但是你可能会想,我的 JSP 文件也放在这个目录下面呀,为什么浏览器可以访问咧。
这时候,应该想想,你的 jsp 是直接通过 浏览器输入什么 http://..../xx.jsp 访问的?不是吧,大部分时候我们是直接访问 控制层 ,再由控制层控制返回那个 jsp 页面给浏览器的。
所以这时候,就不属于直接通过浏览器外部访问这个 JSP 页面了,而是通过了控制层访问的,属于内部访问了,这样 WEB-INF 当然不会禁止内部访问。
你可能又会想,为什么这些 js,css 文件又引用不了,因为这时候已经不属于内部访问了。
那么为什么是外部访问咧,因为当以绝对路径引用的时候,request.getcontextPath()/WEB-INF/js/xx.js, 这时候会转换为 xxx/WEB-INF/js/xx.js,很显然就变成了外部引用了,WEB-INF 拒绝了访问,所以我们一般会放到 WEB-INF 目录外面,这样:xxx/js/xx.js。
相对路径时,如果通过controller后再返回对应的html或jsp页面时,相对路径可能会不是我们想要的,例如,在服务器端,如果某js文件路径为:/js/xx.js,html文件为/html/xx.html,并在在html中写入一下相对路径引用代码<script src="../js/jQuery.min.js"></script>,会有两种结果发生,这里假设filter不拦截访问,并且配置了<mvc:resources location="/js/" mapping="/js/**" />,如果我们直接访问路径为:http://127.0.0.1:8080/(项目名)/html/xx.html,结果很一切正常,但是当我们通过controller映射返回对应的html页面时,可能就会出错了。
例如下面的controller映射如下:
- @Controller
- @RequestMapping("/download")
- public class DownloadController {
- @RequestMapping(value="/develop/*",method=RequestMethod.GET,produces={"text/html"})
- public String developPage() {
- return "xx";
- }
- }
那么这个时候相对路径../js/xx.js在浏览器端解析后将为:http://127.0.0.1:8080/(项目名)/download/js/xx.js,于是悲催的事情就发生了,对应的js文件将得不到正常的引用,原因很简单,路径不对了,自然找不到,网上查找到的资料解释为:导入的js是相对当前请求的路径的,而不是相对于你在服务器文件的放置目录的。因此,正好印证了网上的解释,../js/xx.js被浏览器端解析后地址就是http://127.0.0.1:8080/(项目名)/download/js/xx.js。
总结:尽量将静态资源文件放到 WEB-INF 目录外面,并且以绝对路径引用。