文件 .htaccess 不适用于 URL 有破折号且未应用第二个 RewriteRule
File .htaccess not working with URL that has a dash and 2nd RewriteRule not applied
我的 .htaccess
文件有问题,据我了解 RewriteRule
有助于重写 URL。但是当我尝试以下2种情况时,它不起作用。
#1 第一个 RewriteRule
有效,但第二个无效
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idcat= [L] #working
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idl= [L] #not working
#2 RewriteRule 不适用于破折号,但适用于斜杠和下划线。
RewriteRule ^([a-zA-Z0-9_-]+)-([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #not working
RewriteRule ^([a-zA-Z0-9_-]+)_([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #working
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #working
那么如何解决这些问题呢?有人对我有什么建议吗?
#1 The first Rewriterule works but the second doesn't work
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idcat= [L] #working
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idl= [L] #not working
因为您在两个规则中使用了相同的模式,所以第一个规则总是“获胜”而第二个规则永远不会被触发。这基本上是按如下方式处理的(pseudo-code):
if (the URL matches the pattern "^([a-zA-Z0-9_-]+)$") {
rewrite the request to "index.php?idcat=<url>"
}
elseif (the URL matches the pattern "^([a-zA-Z0-9_-]+)$") {
rewrite the request to "index.php?idl=<url>"
}
如您所见,第二个代码块从未被处理,因为表达式相同。
换句话说,你如何确定/foo
形式的请求应该重写为index.php?idcat=foo
还是[=15] =]?您不能将请求重写到两者。
在这种特殊情况下,您或许可以将所有内容重写为 index.php?id=<url>
,并让您的脚本决定它应该是 idcat
还是 idl
。否则,两个 URLs(以及因此用于匹配 URLs 的 patterns 需要有一些不同之处,使您能够确定URL 应该如何重写。
#2 The Rewriterule doesn't work with dash but works with slash and underscore.
RewriteRule ^([a-zA-Z0-9_-]+)-([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #not working
RewriteRule ^([a-zA-Z0-9_-]+)_([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #working
这两个规则都有相同的问题,具体取决于所请求的 URL。这是因为您使用的 patterns/regex 是“不明确的”。用于匹配 idl
和 iddis
值的两个子模式(delimiter 的任一侧)中的每一个都包含与预期分隔符相同的字符, -
或 _
。但是,在第三条规则(未显示)中,您使用 /
作为分隔符,它不会出现在周围的子模式中,因此没有歧义,
例如,/foo-bar-baz
形式的 URL 应该如何(或者您会期望)第一条规则匹配?由于第一个子模式使用 greedy 量词 +
,它将捕获 foo-bar
和 baz
并将请求重写为 index.php?idl=foo-bar&iddis=baz
.
为避免这种“歧义”,您需要确保子模式之间的分隔符(即 idl
和 iddis
的值之间)与子模式中使用的字符不同 (或至少两个子模式之一)。
这通常可以通过使正则表达式尽可能具体来解决。 IE。仅匹配 idl
和 iddis
.
中的有效字符
要开始解决此问题,您需要首先确定要匹配的精确 URL,然后再实施匹配规则。
我的 .htaccess
文件有问题,据我了解 RewriteRule
有助于重写 URL。但是当我尝试以下2种情况时,它不起作用。
#1 第一个 RewriteRule
有效,但第二个无效
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idcat= [L] #working
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idl= [L] #not working
#2 RewriteRule 不适用于破折号,但适用于斜杠和下划线。
RewriteRule ^([a-zA-Z0-9_-]+)-([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #not working
RewriteRule ^([a-zA-Z0-9_-]+)_([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #working
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #working
那么如何解决这些问题呢?有人对我有什么建议吗?
#1 The first Rewriterule works but the second doesn't work
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idcat= [L] #working RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?idl= [L] #not working
因为您在两个规则中使用了相同的模式,所以第一个规则总是“获胜”而第二个规则永远不会被触发。这基本上是按如下方式处理的(pseudo-code):
if (the URL matches the pattern "^([a-zA-Z0-9_-]+)$") {
rewrite the request to "index.php?idcat=<url>"
}
elseif (the URL matches the pattern "^([a-zA-Z0-9_-]+)$") {
rewrite the request to "index.php?idl=<url>"
}
如您所见,第二个代码块从未被处理,因为表达式相同。
换句话说,你如何确定/foo
形式的请求应该重写为index.php?idcat=foo
还是[=15] =]?您不能将请求重写到两者。
在这种特殊情况下,您或许可以将所有内容重写为 index.php?id=<url>
,并让您的脚本决定它应该是 idcat
还是 idl
。否则,两个 URLs(以及因此用于匹配 URLs 的 patterns 需要有一些不同之处,使您能够确定URL 应该如何重写。
#2 The Rewriterule doesn't work with dash but works with slash and underscore.
RewriteRule ^([a-zA-Z0-9_-]+)-([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #not working RewriteRule ^([a-zA-Z0-9_-]+)_([a-zA-Z0-9_-]+)$ index.php?idl=&iddis= [L] #working
这两个规则都有相同的问题,具体取决于所请求的 URL。这是因为您使用的 patterns/regex 是“不明确的”。用于匹配 idl
和 iddis
值的两个子模式(delimiter 的任一侧)中的每一个都包含与预期分隔符相同的字符, -
或 _
。但是,在第三条规则(未显示)中,您使用 /
作为分隔符,它不会出现在周围的子模式中,因此没有歧义,
例如,/foo-bar-baz
形式的 URL 应该如何(或者您会期望)第一条规则匹配?由于第一个子模式使用 greedy 量词 +
,它将捕获 foo-bar
和 baz
并将请求重写为 index.php?idl=foo-bar&iddis=baz
.
为避免这种“歧义”,您需要确保子模式之间的分隔符(即 idl
和 iddis
的值之间)与子模式中使用的字符不同 (或至少两个子模式之一)。
这通常可以通过使正则表达式尽可能具体来解决。 IE。仅匹配 idl
和 iddis
.
要开始解决此问题,您需要首先确定要匹配的精确 URL,然后再实施匹配规则。