web开发当中,目录路径的书写是再常用不过了,一般情况下不会出什么问题,但是有些时候出现了问题却一直感到奇怪,所以这里记录一下,彻底解决web开发中路径的问题,开发分为前端和服务端,那么就从这两个方面来分析,想要解决这个问题,首先应该熟练理解Linux系统和Windows系统的路径概念,以及绝对路径和相对路径的概念,这些就不多说了,其实web应用就和我们操作命令行一样,去进出一些目录,因此理解了应用的运行原理,路径就不在感觉那么乱了,下面看一下:
首先是服务端,以php为例,举一个最基本的例子,假如我在本地服务器根目录下建立一个目录,名称为ceshi,然后在目录下建立php应用index.php,那么我们运行该应用要访问:http://localhost/ceshi或者http://localhost/ceshi/index.php其实这样是一样的,不同的是服务器返回给浏览器的东西,导致浏览器显示的路径不太一样,那么index.php运行的目录就是应用的当前目录,当然就是ceshi目录下,这是当前目录,那么现在包含一个文件,和index.php相同目录下,也就是测试目录下,有一个目录include,目录下有一个文件inc.php、还有一张图片123.jpg,我们首先包含inc.php那么我们使用相对路径就是./include/inc.php或者include/inc.php这样包含过来了,没任何问题,这时候inc.php的功能是显示图片123.jpg这其实属于前端的,为了方便理解,还是放这了,如果inc.php显示图片,那么再简单不过了,直接输出就可以了,但是包含文件的本质是相当于把被包含文件内容原封不动的复制到件当中,就是说当程序运行的时候,所有代码都是跑在index.php当中,这样,调用图片很显然应该是件的相对路径,应该写成
这样就没问题了,另外包括解压文件的类的路径也应该严格按照这个思维来写,就不会出错,认准当前运行的程序和当前路径的概念。
如果我们用绝对路径去包含文件怎么包含呢?绝对路径不就是相对于根目录吗,于是会写/ceshi/include/inc.php,结果运行报错,所以关于绝对路径我们不应该相对于服务器根目录,而是操作系统根目录,Linux是系统根目录,Windows就是当前驱动器的根目录,也就是磁盘根目录,因为php虽然是web应用,但是在本地服务器也是一款本地应用,服务器是建立在操作系统之上的,所以本地应用所能达到的访问空间和操作系统等同,除非设置了权限,我的服务器根目录是E:\Webapps那么调用应该写成/Webapps/ceshi/include/inc.php这样才可以,这也是服务端和客户端的不同。
另外我们用框架开发比如ThinkPHP,开启pathinfo模式后浏览器访问url会是这样http://localhost/abc/abc/abc这种情况,如果我们此时包含inc.php该怎么包含?当然绝对路径不变,那么相对路径呢,因为表面上看,路径运行了好几层,实际上入口文件还是index.php也就是说此时程序运行在入口文件处、也就是服务器根目录下,那么调用inc.php就很简单了,是:./ceshi/include/inc.php,我们不管包含多少文件,最后都运行在当前程序下,按照这个原理就可以了,包含文件不会出错,但是我们要调用图片呢,我们都是通过输出语句输出标签,标签是在浏览器端被解析的,浏览器访问的最大范围是默认就是服务器根目录,所以浏览器是按照url表面显示的路由来解析文件,浏览器不知道入口文件,在浏览器看来/abc/abc/abc是一个分层的,所以直接写./ceshi/include/123.jpg是无法显示文件的,相对路径应该写../../ceshi/include/123.jpg这样就显示了,但是用参数模式还可以这样访问http://localhost/abc?m=abc&a=abc这样浏览器认为目前是根目录下,当然../../直接在浏览器端是出不去的,这是特殊情况,但是其他情况会出问题,所以为了保证通用,一般用绝对路径,就是/ceshi/include/123.jpg这样任何时候都可以放心调用了,以上这些本质就是服务器端看当前目录,浏览器端只根据url的表面显示去寻找,并且不会超过根目录之外。只要不是显示输出在前端,那么都根据服务端规则来处理,比如上传文件,解压文件等等服务端操作,都是按照程序运行目录来算,只有一些资源文件显示在前端,就按浏览器的方式处理。
另外看一下前端,前端都是浏览器从服务器请求的,浏览器都是根据URL的情况来请求文件,按照这个就没问题,比如刚才的图片输出问题,如果写./ceshi/include/123.jpg当前访问路径是/abc/abc/abc那么浏览器请求路径就是/abc/abc/ceshi/include/123.jpg很明显会出问题,这个就是最基本的规则,另外再看HTML页面,这个就简单了,HTML页面是被浏览器解析,也就是服务器将HTML文件拆分开来发送到浏览器浏览器逐步解析、渲染,最后呈现页面,那么调用的所有文件都是根据当前html文件的相对路径,或者直接写文件的真实的相对服务器根目录的绝对路径也没有问题。
前端另外还有js和css,我们来看一下,如果在页面的顶部写上一段代码来为body添加背景,这个很简单使用相对路径调用背景文件即可:
<style type="text/css">
body{
background-image:url(include/123.jpg);
background-repeat: repeat-y;
}
</style>
这样运行肯定没有任何问题,当前目录下的include/123.jpg正确调用,但是我们想把css单独放在一个文件里然后用标签引用会怎么样呢,引用当然没问题,而css文件里的资源似乎有点问题,我们在当前目录下建一个css目录把代码原封不动的放进去,我们只需要一句便可以引用了,结果发现没有效果,所以css里的所有资源路径,应该是相对于css文件的路径才可以,所以可以写成../include/123.jpg或者干脆/ceshi/include/123.jpg都没问题,就是说浏览器请求的时候是分开请求的,css并不是像包含文件一样直接放到执行文件下,而是被浏览器单独解析,显然,图片调用应该是相对于css文件的路径。
那么JavaScript呢,我们首先写个标签加入一张图片,没有任何问题,然后我们在下面写上一句最简单的JavaScript代码来操作一下图片,
<script type="text/javascript">
document.getElementById('img').src='include/class.jpg';
</script>
现在刷新页面,图片显示的不是123.jpg而是class.jpg了,并且这段代码只能放到标签之后,原因很简单浏览器是按顺序解析的,如果放到前面,运行js时会找不到id后来解析的时候会重新加载img标签,所以不生效,因此我们只能放在图片之后,可以是