最近在项目中使用 apache 做页面静态化,需要实现一个需求:
当用户访问 index.html 的时候,让 apache 判断如果index.html 不存在,就转向 index.do 这个路径。
index.do 就是生成静态页面 index.html 的,以后用户再访问 index.html 就会直接使用 index.html 这个静态页面了,从而达到网站静态化的目的。
在配置 apache 让 apache 判断 index.html 文件是否存在的时候出现了问题。
首先需要开启 rewrite 功能,按如下步骤操作:
1、去掉 httpd.conf 文件中 #LoadModule rewrite_module modules/mod_rewrite.so 前面的 # 号,表示开启 rewrite 模块功能。
2、在httpd.conf 中添加如下配置进行测试
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^/a\.html$ /b.html [L]
测试结果是:不管 a.html 文件是否存在,都会转到 b.html 。
百思不得其解,然后各种百度Google,也没有找到答案。
思考到深夜,也没有想出为什么。第二天继续开始慢慢分析原因…………
首先可以确定的是:之所以每次都会跳转到 b.html 原因肯定是 apache 就是认为 a.html 不存在。我的 a.html 就是静静的躺在那里,为什么 apache 就是认为她不存在呢?
我们访问文件的时候输入的URL 规则都是 http://www.test.com/a.html、http://www.test.com/user/detail.html ………等等。
于是猜想:使用 %{REQUEST_FILENAME} 得到的会不会是只是 /a.html、/user/detail.html 这样的路径,apache 不会去追加我们项目的目录路径后再判断是否存在?
然后我就把我上面测试的 a.html 文件放到 linux 的根目录 / 下面,然后进行测试。
结果是令人开心的,这个时候显示了 a.html 的内容,并没有跳转到 b.html。
所以确定了一个结论:
使用 RewriteCond %{REQUEST_FILENAME} !-f 来验证一个文件是否真正存在的时候,验证的是一个实际的物理文件的实际物理路径,不会自动以当前项目的目录为Base目录。RewriteCond 的 input 文件应该是一个绝对路径的。
我的项目Base 目录为:/svcroot/runtime/webstatic/shanhyweb ,我的 a.html 和 b.html 都放在这个目录下。
那么我们在判断文件是否存在的时候,应该这样写:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
这样处理,就解决问题了。哈哈~~
之所以网上很少能找到解决问题的资料,可能是因为大家用的一般都是 .htaccess 文件的配置方法,或者一般将项目的目录放在系统的根路径下面。所以才不会出现问题。
如果我们使用 .htaccess 文件配置,则不需要使用 %{DOCUMENT_ROOT} ,因为 .htaccess 是目录级别的,apache 会自动加上项目路径。
而在http.conf文件里面的进行配置,apache不会自动加上项目目录路径。
-----------------------------
(完)