快速、可靠地重定向到单个规范 URL?

问题描述 投票:0回答:0

我目前有一个混乱的 Apache .htaccess 文件来(尝试)确保我网站上每个页面的规范 URL,并且该 URL 不反映底层技术或页面是文件还是目录。例如:

  • recipes/frigidaire.html
    具有 example.com/recipes/frigidaire/ 的规范 URL; recipes/frigidaire.htmlrecipes/frigidaire.phprecipes/frigidaire/index.html(例如)的请求都重定向到规范 URL。
  • recipes/index.php
    具有 example.com/recipes/ 的规范 URL 和对 recipes/index.phprecipes/index.html 等的请求,所有重定向到规范 URL。

这意味着,如果我稍后将

frigidaire.html
更改为
frigidaire.php
,例如,URL不会更改。或者,如果我将一些子页面添加到
frigidaire
,这样它就从一个文件变成一个目录,它的URL也不会改变。

任何对页面的请求,如果它还不是规范的 URL,将被重定向到规范的 URL。

具体来说,我确实希望无论URL如何都显示正确的页面。我希望显示正确的页面 只有 对规范 URL 的请求;该页面可能的其他请求应重定向到规范 URL。

这是我的大多数域的顶级 .htaccess 文件中的示例。我已经大大减少了。涵盖的案例更多。例如,真实集或重写中的文件扩展名更多;并且完整的集合处理某些类型文件的内容处理问题。

#If the request is for an existing directory, we're done
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)$      -       [L]

#Apache lets dynamic files accept slashes at the end
#redirect dynamic file endings to their "directory" equivalent
RewriteCond %{ENV:REDIRECT_STATUS}      ^$
RewriteRule ^(.*)/index\.php/?$    {% page SELF -relative %}$1/   [R=301,L]
RewriteCond %{ENV:REDIRECT_STATUS}      ^$
RewriteRule ^(.*)\.php/?$    {% page SELF -relative %}$1/   [R=301,L]
RewriteCond %{ENV:REDIRECT_STATUS}      ^$
RewriteRule ^(.*)/index/?$    {% page SELF -relative %}$1/   [R=301,L]

#redirect known file endings to their "directory" equivalent
RewriteCond %{ENV:REDIRECT_STATUS}      ^$
RewriteRule ^(.*)\.(au|bin|cpt|doc|dot|dvi|eps|exe|gif|html|jpe?g|manifest|php|pdf|png|ps|ps\.Z|ps\.z|ps\.gz|rss|rtf|rtf\.gz|shtml|sit|sit\.hqx|tar|tar\.gz|tar\.Z|txt|TXT|xhtml|zip.uu)$        {% page SELF -relative %}$1/    [R=301,L]
#need to put .Z on its own, or it takes precedence over ps.Z, etc.
RewriteCond %{ENV:REDIRECT_STATUS}      ^$
RewriteRule ^(.*)\.(hqx|Z|zip)$        {% page SELF -relative %}$1/    [R=301,L]

#if it has no slash after it, add a slash and start over
#we should not have any .html, etc., at this point because we redirected them above
RewriteCond %{ENV:REDIRECT_STATUS}      ^$
#if there is a query string, we can't do this, because the slash will be appended after the query string, not after the filepath
RewriteCond %{QUERY_STRING}      ^$
RewriteCond %{THE_REQUEST}      ({% page SELF -relative %}[^\ ]+)
RewriteRule ^(.*[^/])$  %1/ [R=301,L,NE]

#Get the base path without the slash
RewriteRule ^(.*)/$     $1      [E=NEWCHECK:$1]

#If there is a .html file, use it
RewriteCond {% page SELF -fullpath %}%{ENV:NEWCHECK}.html  -f
RewriteCond %{THE_REQUEST}      ({% page SELF -relative %}[^\ ]+)/
RewriteRule ^(.*)/$     %1.html [L,NE]

#If there is an .xhtml file, use it
RewriteCond {% page SELF -fullpath %}%{ENV:NEWCHECK}.xhtml -f
RewriteRule ^(.*)/$     $1.xhtml [L]

#If there is a .php file, use it
RewriteCond {% page SELF -fullpath %}%{ENV:NEWCHECK}.php -f
RewriteRule ^(.*)/$     $1.php [L]

#If there is a .txt file, use it
RewriteCond {% page SELF -fullpath %}%{ENV:NEWCHECK}.txt -f
RewriteCond %{THE_REQUEST}      ({% page SELF -relative %}[^\ ]+)/
RewriteRule ^(.*)/$     %1.txt [L,NE]

很多similarquestionssolutions在那里,都像我一样使用重写规则。在不使用重写的情况下,有没有更简单的方法在 Apache 中执行此操作?这是一组漫长而曲折的重写,我一直认为应该为此设置一个简单的 .htaccess 设置。这似乎是一个足够普遍的要求。

我担心这种对每个请求的重写会给服务器带来不必要的负担。我也知道它非常复杂,并且仍然存在无法产生我想要的结果的边缘情况。

但是我找不到类似的东西

Options +FolderizeAllURLs +Redirect

我看到了使用MultiViews的建议。

Options +MultiViews

但这似乎无法处理重定向到规范 URL 的问题。它还似乎允许各种奇怪的 URL。例如,

recipes/News/2023.php
将与以下请求一起显示:

  • example.com/recipes/News/2023
  • example.com/recipes/News/2023/index.php
  • example.com/recipes/News/2023/four/score/and/seven/years/ago

随着错误的产生,允许指向这个特定页面的非常错误的 URL 永无止境地扩展,这与我正在寻找的几乎完全相反:

  1. 一个规范的 URL 就可以了;
  2. 引用 URL 的常用方法将重定向到那个规范的 URL。
  3. 实际不正确的 URL 将以正常方式失败(通常是 404)。

是否有更可靠的方法和/或服务器密集程度较低的方法?

apache .htaccess redirect canonicalization
© www.soinside.com 2019 - 2024. All rights reserved.