我正在尝试内部重定向一些 URL。
从:
https://example.com/?cat=123
到
https://example.com/?cat=456
在.htaccess
文件中我写道:
<IfModule mod_rewrite.c>
RewriteRule ^?cat=123$ https://example.com/?cat=456 [R=301,L]
</IfModule>
但这会导致 500 服务器错误,经过反复试验,我发现这是由?
中的字符引起的?cat=123
。
如果我删除?
,虽然重定向不起作用,但 500 错误就会消失。
?
此外,只要旧的 URL 中没有重定向就可以正常工作。
这很好用:
RewriteRule ^cat=123$ https://example.com/?cat=456 [R=301,L]
这表明?
在新的 URL 中不会引起问题。
看来.htaccess
文件中存在字符识别问题?
。
有人知道如何解决或避免这个问题吗?
答案1
问题不?
在于 URL。问题在于您尝试使用的正则表达式...
^?cat=123$
此正则表达式无效 - 这是 500 内部服务器错误的原因(错误日志会报告无法编译正则表达式 - 或类似内容)。这并不是特例.htaccess
- 任何正则表达式解析器都会抛出相同的错误。
是?
正则表达式中的特殊元字符,使前一项成为可选项。但^
无法量化,因此不能是“可选的”。
然而,你试图这样做的方式存在更根本的错误。RewriteRule
图案仅匹配 URL 路径,这特别排除了查询字符串(如?
URL 中所示)。因此,尝试匹配RewriteRule
指令中的查询字符串永远不会奏效。
为了匹配查询字符串(即第一个之后的所有内容)?
,您需要一个RewriteCond
与服务器变量匹配的指令QUERY_STRING
。
例如,要从 重定向https://example.com/?cat=123
到https://example.com/?cat=456
,您需要执行如下操作:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^cat=123$
RewriteRule ^$ https://example.com/?cat=456 [R=302,L]
不?
作为QUERY_STRING
(或 URL 路径)值的一部分出现。
如果您特别需要匹配主机名,那么您将需要另一个RewriteCond
与服务器变量匹配的指令HTTP_HOST
。如果您已经规范化了方案+主机名,并且您只有一个域,那么您可以从RewriteRule
代换。
仅当您确认其按预期工作后,才将 302(临时)重定向更改为 301(永久)。301 会被浏览器永久缓存,因此可能会使测试出现问题。
我假设你的代码中一定已经有了一条RewriteEngine
指令。没有必要使用<IfModule mod_rewrite.c>
包装器,除非你将这些指令移植到多个可能未安装 mod_rewrite 的服务器,并且此重定向选修的?
?
只要旧的 URL 中没有重定向就可以正常工作。
在这种情况下,没有查询字符串,只有 URL 路径,所有内容都将由RewriteRule
图案。