[英]Rewriting dynamic URLs
我试图将1个动态URL重写为另一个动态URL,如下所示;
/category?category=News to
/categorysearch/result/?q=news
我想知道是否有人知道如何在htaccess中完成这项工作?
谢谢。
所以最终的EDITED解决方案是(对于您链接的.htaccess):
RewriteCond %{REQUEST_FILENAME} ethical [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)ethical(=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=%3 [L,R]
如果我使用当前问题中的“类别”术语:
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)category(=|%3D)([^&]+) [NC]
RewriteRule .* /categorysearch/result/?q=%3 [L,R]
但第一个更清楚,类别这个词并不是随处可见。 如果你想添加小写转换,我们甚至会做:
# outside of a Directory section
RewriteMap lowercase int:tolower
# in a Directory section (not a .htaccess)
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)category(=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%3} [L,R]
但正如评论这最后一个与tolower无法在.htaccess中工作 - 无论如何.htaccess很糟糕,真的,对于表演,你应该考虑设置AllowOverride None并将所有这些东西都移到VirtualHost中。 而像rewriteMaps这样的好东西不能用于.htaccess文件。
所以现在我将解释规则。 首先,你的情况的主要问题是“?”之后的一切 是query_string ,而不是请求的文件名 。 大多数rewriteRules尝试处理请求的文件名。 所以我首先检查我们是否有针对性的问题文件名:
RewriteCond %{REQUEST_FILENAME} category [NC]
然后我们将处理查询字符串(问号后面的所有内容)。 我们本可以编写一些非常简单的东西:
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} ^category=(.+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%1} [L,R]
为了捕获RewriteRule可用的变量%1之后的所有内容?category = 但QUERY_STRING参数有几个问题,让我们尝试一下它的乐趣:
编辑 :
我的第一个答案是:
RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} [^|&|%26|%20][category](=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%2} [L,R]
随着[^|&|%26|%20]
捕获事实,它可能是起始参数或&和空格后的参数, %26
是&urlencoded。
但这是错误的 ,感谢@mootinator评论我已经检查了一点,[类别]匹配'类别',但'atcatcategory'和这些字母的任意组合。
RewriteCond %{QUERY_STRING} category(=|%3D)([^&]+) [NC]
匹配'category'参数,删除^
允许将此参数放在任何位置。 但这也会匹配一个名为subcategory
的参数。 所以第一个字母必须是空格或&(或查询字符串的开头)。
这就是[^|&|%26|%20]
,这意味着我开始链OR和/或空格或者在urlencoded中。 但这也是错误的 , ^
[]
意味着否定。 所以我们需要在这里使用匹配的括号: (^|&|%26|%20)
,现在它可以工作,唯一的问题是参数的值现在是%3而不是%2
然后我们抓住(类别)单词,确切地说我们应该事实上用大写字母,小写字母和urlencoded版本的字母大小写一个字母,大写字母,有点像awfull [c|C|%43|%63][a|A|%61|%41][t|T|%74|...]to be continued
- 我应该使用括号而不是括号,地狱,检查urlencoded字符列表 。
(=|%3D)
是urlencoded与否的'='字符。
我本可以使用
。 由于使用了第一个匹配的括号,我们必须使用%2变量而不是%1。 [=|%3D]
但
%3D
在这种情况下不匹配,我不明白为什么(mod_rewrite是一个奇怪的东西)
然后我们有好的([^&]+)
,这意味着什么,但不是'&'。
在这些条件之后我们应用RewriteRule。 我们采取一切(这是.*
)并将其重定向到/catalogsearch/result/?q=%2
我们使用%3
而不是$1
或$3
因为我们不会在rewriteRule上捕获任何内容但是在之前的条件( %3
是最后一个条件的第三个捕获数据,因此它是([^&]+)
)。 如果在rewriteRule中添加QSA标志([L,R,QSA]),您甚至可以获取最终查询字符串上的其他参数,以便:
ethical?bar=toto& ethical=Foo&zorglub=titi
=> is redirected to
catalogsearch/result/?q=foo&bar=toto&%2520ethical=Foo&zorglub=titi
如果我玩一个小网址编码:
ethical?bar=toto%26 ethical%3DFoo&zorglub=titi
=> is redirected to
catalogsearch/result/?q=foo&bar=toto%2526%2520ethical%253DFoo&zorglub=titi
但这不是剧本的结束,我会让你处理所有你想要的urlencoding问题你想要检测Foo值的所有变化并将它们与tolower混合(这里它已经坏了)。 您甚至可能在参数或额外属性中没有编码网址的问题,但这很有趣:-)
根据您要做的事情以及具体事项的具体情况,有两种选择。
第一个是Rob W的解决方案,它应该将用户从/category?category=News
重定向到/categorysearch/result/?q=News
如果看起来像您的URL区分大小写,那么您可能需要查看如下所示的PHP脚本:
$matches = array();
if( preg_match( "/^/category\?category=(.+)/", $_SERVER['REQUEST_URI'], $matches ) ) {
header( 'Location: http://' . $_SERVER['HTTP_HOST'] . '/categorysearch/result/?q= . strtolower($matches[1]) );
}
else {
//ERROR HANDLING
}
一旦确定,您可以使用类似以下的规则来使用完全小写的参数进行重定向。
RewriteRule ^category\?category=(.+)$ redirect.php [L]
放在一起,这个解决方案会重定向/category?category=News
to /categorysearch/result/?q=news
我认为
RewriteRule ^/category?category=(.*) /categorysearch/result/?q=news
会做的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.