我在.htaccess
:
RewriteRule ^images/([^/\.]+)/(.+)$ themes/current/images/$1/$2 [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^images/([^/\.]+)/(.+)$ modules/$1/images/$2 [L,NC]
这个想法是它做了以下事情:
// Rewrite this...
images/calendar/gear.png
// ... to this
themes/current/images/calendar/gear.png
// HOWEVER, if that rewritten path doesn't exist, rewrite the original URL to this:
modules/calendar/images/gear.png
这里唯一改变的是calendar
和gear.png
,其中第一个可以是任何其他单个单词,后者是文件名(可能带有路径)到图像文件。
我可以将原始URL重写为第一次重写,如示例所示,但我不能做的是让我的.htaccess从另一个备用位置提供文件,如果第一个位置404s。我的印象是,在我的第一个[L]
中不使用RewriteRule
会重写RewriteCond
的网址。
我遇到的问题是,浏览器只显示404到第一个重写路径(themes/current/calendar/gear.png
),而不是回退到modules/calendar/gear.png
,而不是提供后备文件。我做错了什么?
请注意我的正则表达式并不完美,但我可以稍后改进。现在我对自己的重写逻辑感到担忧。
答案 0 :(得分:1)
堕落的规则充满了错误。我的一般建议是,除-
之外的替换字符串应该触发内部重定向以重新启动.htaccess
解析。这避免了subrequest和URI_PATH错误。
接下来,一旦你去了404,再次根据我的经验,这是不可恢复的。我有一个片段,它与你想要做的事情类似:
# For HTML cacheable blog URIs (a GET to a specific list, with no query params,
# guest user and the HTML cache file exists) then use it instead of executing PHP
RewriteCond %{HTTP_COOKIE} !blog_user
RewriteCond %{REQUEST_METHOD}%{QUERY_STRING} =GET [NC]
RewriteCond %{ENV:DOCUMENT_ROOT_REAL}/blog/html_cache/$1.html -f
RewriteRule ^(article-\d+|index|sitemap.xml|search-\w+|rss-[0-9a-z]*)$ \
blog/html_cache/$1.html [L,E=END:1]
请注意,我在文件系统空间而不是URI(位置)空间中进行条件测试。所以这会在你的情况下映射到
RewriteCond %{DOCUMENT_ROOT}/themes/current/images/$1/$2l -f
RewriteRule ^images/(.+?)/(.+)$ themes/current/images/$1/$2 [L]
虽然做一个phpinfo()来检查您的托管服务提供商是否使用 DOCUMENT_ROOT 的替代方案,如果它是共享托管服务,例如我的 DOCUMENT_ROOT_REAL DOCUMENT_ROOT_REAL 强>
第二条规则将在内部重定向后的第二个处理过程中被选中。