如果第一次尝试失败则重定向到后备文件

发布于 2025-01-05 00:35:00 字数 981 浏览 1 评论 0原文

我的 .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

这里唯一改变的是 calendargear.png ,第一个可以是任何其他单个单词,后者是图像文件的文件名(可能带有路径)。

我可以将原始 URL 重写为第一个重写,如示例中所示,但我不能做的是让我的 .htaccess 在第一个位置 404s 的情况下从另一个后备位置提供文件。我的印象是,在我的第一个 RewriteRule 中不使用 [L] 会重写 RewriteCond 的 URL。

我遇到的问题是,浏览器没有提供后备文件,而是仅显示第一个重写路径 (themes/current/calendar/gear.png) 的 404,而不是回退到modules/calendar/gear.png。我做错了什么?

请注意,我的正则表达式并不完美,但我可以稍后对其进行改进。现在我关心的是重写逻辑本身。

I have this in my .htaccess:

RewriteRule ^images/([^/\.]+)/(.+)$ themes/current/images/$1/$2 [NC]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^images/([^/\.]+)/(.+)$ modules/$1/images/$2 [L,NC]

The idea is that it does the following:

// 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

The only things that change here are calendar and gear.png, the first of which could be any other single word and the latter the file name (possibly with path) to an image file.

I can rewrite the original URL to the first rewrite as shown in the example just fine, but what I cannot do is get my .htaccess to serve up the file from the other, fallback location if the first location 404s. I was under the impression that not using [L] in my first RewriteRule would rewrite the URL for RewriteCond.

The problem I'm having is that instead of serving the fallback file, the browser just shows a 404 to the first rewritten path (themes/current/calendar/gear.png), instead of falling back to modules/calendar/gear.png. What am I doing wrong?

Please note that my regex isn't perfect, but I can refine that later. Right now I'm concerning myself with the rewrite logic itself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

抱着落日 2025-01-12 00:35:00

Fallthrough规则充满了错误。我的一般建议是,除 - 之外的任何具有替换字符串的规则都应触发内部重定向以重新启动 .htaccess 解析。这避免了子请求和 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。

第二条规则将在内部重定向之后的第二次处理中被选取。

Fallthrough rules are fraught with bugs. My general recommendation is than any rule with a replacement string other than - should trigger an internal redirect to restart the .htaccess parse. This avoids the subrequest and URI_PATH bugs.

Next once you go to 404, again in my experience this is unrecoverable. I have a fragment which does something similar to what you are trying to do:

# 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]

Note that I do the conditional test in filesystem space and not URI (Location) space. So this would map in your case to

RewriteCond %{DOCUMENT_ROOT}/themes/current/images/$1/$2l -f
RewriteRule ^images/(.+?)/(.+)$ themes/current/images/$1/$2 [L]

Though do a phpinfo() to check to see if your hosting provider uses an alternative to DOCUMENT_ROOT if it is a shared hosting offering e.g an alternative environment variable as mine uses DOCUMENT_ROOT_REAL.

The second rule will be picked up on the second processing past after the internal redirect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文