找不到图片,找不到js脚本,找不到css样式表,都属于这个问题。
要演示这个问题,是非常容易的,只需要满足两个条件:
-
forward前后的jsp页面不在一个目录下。
-
forward后的jsp页面里使用相对路径引用一些资源,图片,js脚本,css样式表什么的。
03-04里就模拟了这样一个环境,你进入http://localhost:8080/03-04/,选择“有问题的”:
打开03-04可以看到如下的目录结构:
|--+ 03-04
|--- index.jsp
|--- test.jsp
|--+ result
|--- success.jsp
|--- failure.jsp
|--- lingo.png
刚才咱们看到的页面是failure.jsp,它里边显示图片的部分是:
<img src="lingo.png" />
这时候就有疑问了,lingo.png和failure.jsp明明在同一个目录下,为什么无法显示。
现在请在无法显示的图片上,点击鼠标右键,选择属性,让我们看一下图片的请求地址:
图片的位置本来在http://localhost:8080/03-04/result/lingo.png,但请求的地址却是http://localhost:8080/03-04/lingo.png。问题就是丢掉了中间的/result。
再试一次index.jsp上的“没问题的”:
这次我们看到的页面是success.jsp,它里边显示图片的部分是:
<img src="result/lingo.png" />
结果手工加上result这段路径后就可以显示图片了。
这个问题还要追溯到浏览器对html的处理方式,在html里包含的图片,css样式表,js脚本,视频等等外部资源,都需要浏览器再次向服务器发起请求。
如果这些外部资源使用了相对路径,浏览器就会在当前请求路径的基础上,加上相对路径拼接出完整的http请求,发送给服务器。这个例子中,我们请求http://localhost:8080/03-04/test.jsp,浏览器得到的当前路径就是http://localhost:8080/03-04/,failure.jsp中图片的相对路径是lingo.png,那么拼接的结果是http://localhost:8080/03-04/lingo.png。
不要怪浏览器太傻,是因为使用forward的时候浏览器并不清楚这些改变。它一直认为,既然自己请求的是test.jsp,返回的自然就是test.jsp的内容,那么再使用test.jsp当作当前路径去计算相对路径当然没有问题。是我们欺骗了浏览器,在服务器偷偷改变了请求流向,返回了其他页面的内容。
清楚了以上的请求流程,就知道如何应对这种问题了。
-
第一种方法:不要在不同目录之间使用forward做请求转发,保证当前路径不发生变化。
-
第二种方法:像上例一样修改图片路径,或全部改为绝对路径。
请根据实际需要进行选择。