相对路径css / js的mod_rewrite问题

时间:2011-04-29 09:25:01

标签: regex apache .htaccess mod-rewrite redirect

嗨,我有一个问题。 我想获得所有请求重定向到主目录中的索引文件,我已经实现了这一点,但相对路径存在问题。
当我输入地址时:mydomain.com/something它可以正常工作,因为路径是相对于主目录的。
问题在于我放了类似的东西:mydomain.com/something/somethingelse。

.htaccess文件:


Options FollowSymLinks
RewriteEngine On
# ignore anything that's an actual file
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
# redirect all other traffic to the index page
RewriteRule . index.php [L]

关于如何让css / j工作的任何想法?


编辑:

问题是当输入的路径有多个斜线时,不会加载css / js文件,如:mydomain.com/something/somethingelse

4 个答案:

答案 0 :(得分:11)

对于静态文件(css,js,images等)使用绝对路径无疑更好。但是如果你在多个页面中有很多这样的实例,那么考虑使用HTML base tag来指定相对路径的默认URL。例如:

<base href="http://www.example.com/static/" />

答案 1 :(得分:3)

使用<base> - 标签是一个很好的解决方案,大多数浏览器似乎都能很好地处理它。除了IE存在一些问题,正如预期的那样......显然你还可能遇到其他一些有趣的问题,see discussion here

所以对于那些不能选择的人来说,我已经研究过另一种选择(&#34;艰难的方式&#34;)。

通常你存储css / js /静态图像/其他类似的东西:

index.php
js/
css/
imgs/

并且您希望javascript和样式表等可用,无论url中有多少斜杠。如果您的网址为/site/action/user/new,则您的浏览器会请求

/site/action/user/css/style.css
/site/action/user/css/framework/fonts/icons.ttf
/site/action/user/js/page.js
/site/action/user/js/jquery/jquery.min.js
/site/action/user/js/some/library/with/deep/dir/structure/file.map

所以这里有一些重写规则让apache解决这个问题......首先,如果目标实际存在于磁盘上,请不要重写:

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [L,QSA]

总之,IF reqest filename是一个目录或者IF请求文件名是一个文件,然后不重写( - ),最后一个规则(L)并传递任何GET参数(QSA,查询字符串追加)。您也可以使用

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^.*$ - [L,QSA]

如果你还需要符号链接。接下来我们希望找到javascript和样式表,即使请求假设一个错误的基目录,如上所示。

RewriteRule ^.*/js/(.*)$ js/$1 [L]      
RewriteRule ^.*/css/(.*)$ css/$1 [L]

模式非常明显,只需替换“css&#39;目录名称。这仍然存在问题,尤其是对于包含大量javascript和样式表,库等的大型网站而言 - 正则表达式是贪婪的。例如,如果你有一个像这样的javascript目录:

js/some/library/js/script.js

并且您的请求转到/site/action/user/new,浏览器将请求/site/action/user/new/js/some/library/js/script.js,然后重写引擎将重写为

js/script.js

因为第一个.*贪婪且匹配/site/action/user/new/js/some/library。由于"the rewrite engine repeats all the rules until the URI is the same before and after an iteration through the rules."

,切换到非贪婪的正则表达式并没有多大意义

还有另一个问题,那就是每个需要免除重写的目录,相对而言是昂贵的#34;需要正则表达式。只需将每个静态组件放入带有&#34;异常&#34;的子目录中,就可以解决这两个问题。名字(实际上这是最好的解决方案 - 任何有更好想法的人请发布)。

目录结构如下所示:

index.php
mystrangedir/js/
mystrangedir/css/
mystrangedir/imgs/

当然,这需要在代码中的任何位置插入 - 对于具有大量现有代码库的项目,这可能很棘手。但是,您只需要一个正则表达式用于目录免除:

RewriteRule ^.*/mystrangedir/(.*)$ mystrangedir/$1 [L]

自动构建系统(如gulp,grunt ....)可用于检查是否&#34; mystrangedir&#34;不存在作为目录低于其自身的目录(这将再次甩掉重写引擎)。

随意将mystrangedir重命名为更合理的内容,例如static_content但更明智的是,目录名称已经在某些库中使用的可能性越大。如果您想要一个绝对安全的目录名,以前从未使用过,请使用加密哈希,例如: 010f8cea4cd34f820a9a01cb3446cb93637a54d840a4f3c106d1d41b030c7bcb。这很长,无法匹配;你可以通过缩短它来在唯一性和正则表达式之间进行权衡。

答案 2 :(得分:1)

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

尽管有评论,但显然应该有效。

尝试添加RewriteLog和RewriteLogLevel指令,以便为我们提供更好的详细信息。

答案 3 :(得分:1)

这是一个路径解析问题:在基本路径./css上使用相对路径/something时,在/css上解析为/something/somethingelse时,它将被解析为{ {1}}。

这不能(或者不应该)用mod_rewrite修复。使用绝对路径而不是相对路径,因此/something/css代替/css