相对路径 css/js 的 mod_rewrite 问题
Posted
技术标签:
【中文标题】相对路径 css/js 的 mod_rewrite 问题【英文标题】:mod_rewrite problem with relative path css/js 【发布时间】:2011-08-15 09:03:39 【问题描述】:您好,我有一个问题。 我想让所有请求重定向到主目录中的索引文件,我已经实现了这一点,但是相对路径存在问题。 当我将地址设置为: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/js 工作的任何想法?
编辑:
问题是当输入的路径有多个斜杠时,css/js文件没有加载like:mydomain.com/something/somethingelse
【问题讨论】:
你能更清楚地描述哪里出了问题吗? 你试过RewriteCond %REQUEST_FILENAME !-f
吗?
你能更清楚地描述哪里出了问题吗?
我猜当我输入地址 mydomain.com/something/somethingelse/file 时,服务器会尝试获取具有相对路径的 css 文件,例如 ./css 它获取 mydomain.com/something/css 而不是存在
【参考方案1】:
对于静态文件(css、js、图像等)使用绝对路径无疑更好。但是,如果您在多个页面中有很多这些实例,请考虑使用html base tag 为相对路径指定默认 URL。例如:
<base href="http://www.example.com/static/" />
【讨论】:
你是我今天的救星!【参考方案2】:使用<base>
-tag 是一个不错的解决方案,大多数浏览器似乎都能很好地处理它。除了 IE 有一些问题,这是意料之中的......显然你还可以遇到一些其他有趣的问题,see discussion here。
因此,对于无法选择的人,我已经研究了替代方案(“艰难的方式”)。
通常你会像这样存储 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]
换句话说,如果请求文件名是目录或如果请求文件名是文件,则不要重写 (-)、最后一条规则 (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”替换为目录名称即可。这仍然存在问题,特别是对于具有大量 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."
还有一个问题,那就是对于每个需要免于重写的目录,都需要一个相对“昂贵”的正则表达式。这两个问题都可以通过将每个静态组件放入具有“不寻常”名称的子目录中来解决(实际上这是 imo 的最佳解决方案 - 任何有更好想法的人请发布)。
目录结构将如下所示:
index.php
mystrangedir/js/
mystrangedir/css/
mystrangedir/imgs/
当然,这需要在代码中的任何地方插入 - 对于具有大量现有代码库的项目,这可能会很棘手。但是,您只需要一个用于目录豁免的正则表达式:
RewriteRule ^.*/mystrangedir/(.*)$ mystrangedir/$1 [L]
自动构建系统(如 gulp、grunt....)可用于检查“mystrangedir”是否不存在于自身下方的目录中(这将再次引发重写引擎)。
随意将mystrangedir
重命名为更合理的名称,例如static_content
,但越合理,目录名称就越有可能已在某个库中使用。如果您想要一个绝对安全的目录名称,并且之前肯定从未使用过,请使用加密哈希,例如010f8cea4cd34f820a9a01cb3446cb93637a54d840a4f3c106d1d41b030c7bcb
。这是相当长的匹配;您可以通过缩短它来在唯一性和正则表达式性能之间进行权衡。
【讨论】:
【参考方案3】:RewriteCond %REQUEST_FILENAME !-f
RewriteRule . index.php [L]
尽管有 cmets,显然应该可以工作。
尝试添加 RewriteLog 和 RewriteLogLevel 指令以提供更好的细节。
【讨论】:
【参考方案4】:这是一个路径解析问题:当在基本路径 /something
上使用相对路径 ./css
时,它被解析为 /css
,而在 /something/somethingelse
上它被解析为 /something/css
。
这不能(或者说不应该)用 mod_rewrite 修复。使用绝对路径而不是相对路径,所以使用/css
而不是./css
。
【讨论】:
以上是关于相对路径 css/js 的 mod_rewrite 问题的主要内容,如果未能解决你的问题,请参考以下文章
子域 mod_rewrite (htaccess) 到相对目录
如何在 Django 应用程序中使用来自预制 index.html 模板和 css 的相对路径?