重定向不重定向 Apache

Redirect not redirecting on Apache

提问人:Sourav 提问时间:7/18/2023 更新时间:8/19/2023 访问量:54

问:

以下是.htaccess文件的内容

Options All -Indexes
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)? DOMAIN NAME \.in)$ [NC]
RewriteRule .? https://%1%{REQUEST_URI} [R=301,L]
RewriteRule ^itinerary/([A-Za-z0-9-]+)/([A-Za-z0-9]+) details.php?id=$2 [NC,L]
ErrorDocument 404 /404.php

问题是当我输入一个不存在的 url 作为 DOMAIN/non-existing 时,错误重定向可以完美地工作,但是当我使用一些重定向到不存在的 url 时,问题就来了。错误页面无法正确重定向。

示例不存在的链接 显示 404.php ?
域/i-donot-exist 是的
域/我不存在.php 是的
域名/行程/某物/ABC
域名/行程/某物/abc/123
域/行程/某物/登录.php
域名/行程/某物/abc/123/1.php
Apache mod-rewrite url-rewrite-module 错误文档

评论

0赞 MrWhite 7/18/2023
您对“域名”的举例说明使该指令在语法上无效。请只用(或)来表示域名。exampleexample.com
0赞 MrWhite 8/19/2023
很好奇为什么你对这个问题(因为已过期)打了一记赏金,而没有首先评论我现有的答案(或回答/回答其他问题),这些问题已经详细解释了这里到底发生了什么以及为什么它不起作用,并提出了建议的解决方案。(?)但是,正如我的回答中所述,对于#3触发您的Apache错误文档 - 只有您可以回答(可能不可能),因为您没有解释什么是“有效”URL。
1赞 MrWhite 8/19/2023
我用更详细的解释和直接引用您的示例更新了我的答案
0赞 Sourav 8/26/2023
@MrWhite您更新的 ans 解决了问题。谢谢:)

答:

2赞 MrWhite 7/18/2023 #1

该指令定义了一个 Apache 错误文档。当 Apache 确定存在错误时将提供的文档。(这不是像你的标题所暗示的那样通过“重定向”提供的,而是通过“内部子请求”提供的。ErrorDocument

RewriteRule ^itinerary/([A-Za-z0-9-]+)/([A-Za-z0-9]+) details.php?id=$2 [NC,L]

未显示响应的 4 个 URL 都由第 2 个指令(如上所述)“成功”写入。从 Apache 的角度来看,没有 404。控制权已经移交给 PHP 处理请求并根据需要提供适当的 404 响应。(PHP看不到Apache是什么。/404.phpdetails.phpRewriteRuledetails.phpErrorDocument

所以,总而言之:

示例不存在的链接 显示 404.php? 原因
#1 /i-donot-exist 是的 不映射到文件,URL 不重写
#2 /我也不存在.php 是的 不映射到文件,URL 不重写
#3 /行程/某物/ABC URL 重写为details.php?id=abc
#4 /行程/某事/abc/123 URL 重写为details.php?id=abc
#5 /行程/某物/登录.php URL 重写为details.php?id=login
#6 /行程/某物/abc/123/1.php URL 重写为details.php?id=abc

您的前两个示例与上述规则完全不匹配,因此不会发生重写,并且会提供 Apache 404(前提是它们没有映射到物理资源)。ErrorDocument

请注意,URL #3、#4 和 #6 都被重写到非常“相同”的目标!

第二个显然是不正确的(即使不知道它应该重写的 URL)。在正则表达式上没有字符串末尾锚点(即),它基本上重写了太多(如上所示)。表单的任何 URL 都会被重写为 ,似乎丢弃(第 2 个路径段)并忽略 .在不了解有关这里发生的事情的更多信息的情况下,您似乎丢弃了第二个路径段这一事实很奇怪,并且可能会使网站出现重复的内容问题。RewriteRule$/itinerary/<foo>/<bar><anything>details.php?id=<bar><foo><anything>

因此,只需附加一个字符串末尾锚点:

RewriteRule ^itinerary/[A-Za-z0-9-]+/([A-Za-z0-9]+)$ details.php?id=$1 [NC,L]

旁白:我删除了第二个路径段周围的括号(因为您没有使用此捕获组),因此在替换字符串中将反向引用从 更改为 。$2$1

现在,由于正则表达式不再匹配,因此无法重写示例中的最后 3 个 URL(和),因此将提供 Apache 404 错误文档。/itinerary/something/abc/123/itinerary/something/login.php/itinerary/something/abc/123/1.php

但是,(您的第 3 个示例)仍将写入(因为它与上述正则表达式匹配),因此不会为此 URL 提供 Apache 404 错误文档。如果不应重写此 URL,则需要提供其他信息,说明为什么不应重写。/itinerary/something/abcdetails.phpdetails.php

因此,在对正则表达式进行上述调整后,我们现在得到以下结果:

示例不存在的链接 显示 404.php? 原因
#1 /i-donot-exist 是的 不映射到文件,URL 不重写
#2 /我也不存在.php 是的 不映射到文件,URL 不重写
#3 /行程/某物/ABC URL 重写为details.php?id=abc
#4 /行程/某事/abc/123 是的 不映射到文件,URL 不重写
#5 /行程/某物/登录.php 是的 不映射到文件,URL 不重写
#6 /行程/某物/abc/123/1.php 是的 不映射到文件,URL 不重写

如果不更多地了解“有效”URL 的格式,就无法对 #3 做更多的事情。但我怀疑这应该在您的 PHP 脚本中处理,而不是在 Apache 中处理。