简体   繁体   English

重写动态URL

[英]Rewriting dynamic URLs

I' trying to rewrite 1 dynamic URL to another dynamic URL as follows; 我试图将1个动态URL重写为另一个动态URL,如下所示;

/category?category=News to
/categorysearch/result/?q=news

I was wondering if anyone had an idea on how this can be done in htaccess? 我想知道是否有人知道如何在htaccess中完成这项工作?

Thanks. 谢谢。

So the final EDITED solution is (for your linked .htaccess): 所以最终的EDITED解决方案是(对于您链接的.htaccess):

RewriteCond %{REQUEST_FILENAME} ethical [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)ethical(=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=%3 [L,R]

If I use the 'category' terms like in this current question: 如果我使用当前问题中的“类别”术语:

RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)category(=|%3D)([^&]+) [NC]
RewriteRule .* /categorysearch/result/?q=%3 [L,R]

But the first one is more clear, the word category is not used everywhere. 但第一个更清楚,类别这个词并不是随处可见。 If you want to add the lowercase transformation we'll even do: 如果你想添加小写转换,我们甚至会做:

# 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]

But as commented this last one with tolower could not work in a .htaccess -- anyway .htaccess are bad, really, for performances, you should really think about setting AllowOverride None and move all this stuff in a VirtualHost. 但正如评论这最后一个与tolower无法在.htaccess中工作 - 无论如何.htaccess很糟糕,真的,对于表演,你应该考虑设置AllowOverride None并将所有这些东西都移到VirtualHost中。 And nice things such as rewriteMaps cannot work on .htaccess files. 而像rewriteMaps这样的好东西不能用于.htaccess文件。

So Now I'll explain the rules. 所以现在我将解释规则。 First the main problem in your situation is that everything after the "?" 首先,你的情况的主要问题是“?”之后的一切 is the query_string , not the requested filename . query_string ,而不是请求的文件名 And most rewriteRules try to work on the requested filename. 大多数rewriteRules尝试处理请求的文件名。 So I first check we're on the targeted quested filename: 所以我首先检查我们是否有针对性的问题文件名:

RewriteCond %{REQUEST_FILENAME} category [NC]

Then we are going to work on the Query string (everything after the question mark). 然后我们将处理查询字符串(问号后面的所有内容)。 We could have written something quite simplier like that: 我们本可以编写一些非常简单的东西:

RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} ^category=(.+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%1} [L,R]

To catch everything after ?category= in a variable %1 available for the RewriteRule. 为了捕获RewriteRule可用的变量%1之后的所有内容?category = But the QUERY_STRING parameter has several problems, let's try to have some fun with it: 但QUERY_STRING参数有几个问题,让我们尝试一下它的乐趣:

  • url decoding is not yet done on this parameter 尚未对此参数执行url解码
  • category is maybe not the first parameter in the list of parameters category可能不是参数列表中的第一个参数
  • it's maybe even not the last one (&foo=bar) 它甚至可能不是最后一个(&foo = bar)
  • you could have some spaces before 你以前可以有一些空格

EDITED : 编辑

My first answer was: 我的第一个答案是:

RewriteCond %{REQUEST_FILENAME} category [NC]
RewriteCond %{QUERY_STRING} [^|&|%26|%20][category](=|%3D)([^&]+) [NC]
RewriteRule .* /catalogsearch/result/?q=${lowercase:%2} [L,R]

With [^|&|%26|%20] catching the fact it could be the starting parameter or a parameter after an & or a space, %26 is an & urlencoded. 随着[^|&|%26|%20]捕获事实,它可能是起始参数或&和空格后的参数, %26是&urlencoded。

But this was wrong , thanks to @mootinator comment I've checked a little more, [category] is matching 'category' but also 'atcatcategory' and any combination of theses letters. 但这是错误的 ,感谢@mootinator评论我已经检查了一点,[类别]匹配'类别',但'atcatcategory'和这些字母的任意组合。

RewriteCond %{QUERY_STRING} category(=|%3D)([^&]+) [NC]

Is matching the 'category' argument, removing the ^ allows this argument to be placed anywhere. 匹配'category'参数,删除^允许将此参数放在任何位置。 But this would also match an argument named subcategory . 但这也会匹配一个名为subcategory的参数。 So the 1st letter must be a space or & (or the start of the query string). 所以第一个字母必须是空格或&(或查询字符串的开头)。

This was the reason for [^|&|%26|%20] , meaning for me start of chain OR & or space or & in urlencoded. 这就是[^|&|%26|%20] ,这意味着我开始链OR和/或空格或者在urlencoded中。 But that was also wrong , the ^ inside [] means negate. 但这也是错误的^ []意味着否定。 So we need to use here as well matching parenthesis: (^|&|%26|%20) , now it works, the only problem is that the value of the argument is now %3 and not %2 所以我们需要在这里使用匹配的括号: (^|&|%26|%20) ,现在它可以工作,唯一的问题是参数的值现在是%3而不是%2

Then we catch the (category) word, to be really exact we should in fact catch it letter after letter with uppercase, lowercase, and urlencoded version of the letter in lower and uppercase, something like an awfull [c|C|%43|%63][a|A|%61|%41][t|T|%74|...]to be continued -- and I should maybe use parenthesis instead of brackets, hell, check urlencoded characters list here . 然后我们抓住(类别)单词,确切地说我们应该事实上用大写字母,小写字母和urlencoded版本的字母大小写一个字母,大写字母,有点像awfull [c|C|%43|%63][a|A|%61|%41][t|T|%74|...]to be continued - 我应该使用括号而不是括号,地狱,检查urlencoded字符列表

(=|%3D) is the '=' character urlencoded or not. (=|%3D)是urlencoded与否的'='字符。 I could have used [=|%3D] but the %3D is not matched well in this case, I don't understand why (mod_rewrite is a land of strange things) . 我本可以使用 [=|%3D]%3D在这种情况下不匹配,我不明白为什么(mod_rewrite是一个奇怪的东西) Because of this first matching parenthesis used we'll have to use %2 variable and not %1. 由于使用了第一个匹配的括号,我们必须使用%2变量而不是%1。

And then we have the nice ([^&]+) which means anything but not an '&'. 然后我们有好的([^&]+) ,这意味着什么,但不是'&'。

After theses conditions we apply the RewriteRule. 在这些条件之后我们应用RewriteRule。 We take everything (this is .* ) and redirect it to /catalogsearch/result/?q=%2 where we use %3 and not $1 or $3 as we do not capture anything on the rewriteRule but on a condition before ( %3 is the third captured data on the last condition so it's ([^&]+) ). 我们采取一切(这是.* )并将其重定向到/catalogsearch/result/?q=%2我们使用%3而不是$1$3因为我们不会在rewriteRule上捕获任何内容但是在之前的条件( %3是最后一个条件的第三个捕获数据,因此它是([^&]+) )。 If you add the QSA flag ([L,R,QSA]) in the rewriteRule you will even get back other parameters on the final query string so that: 如果在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

And if I play with a little url encoding: 如果我玩一个小网址编码:

ethical?bar=toto%26 ethical%3DFoo&zorglub=titi 
=> is redirected to 
catalogsearch/result/?q=foo&bar=toto%2526%2520ethical%253DFoo&zorglub=titi

But this is not the end of the play, I'll let you handle all the urlencoding problems you could have it you want to detect all variations on Foo value and mix them with the tolower (here it's broken). 但这不是剧本的结束,我会让你处理所有你想要的urlencoding问题你想要检测Foo值的所有变化并将它们与tolower混合(这里它已经坏了)。 You will maybe not even have theses problems of encoded url in your parameters or extra attributes, but that was fun :-) 您甚至可能在参数或额外属性中没有编码网址的问题,但这很有趣:-)

Depending on what you're trying to do and how specific things need to be, there are two options. 根据您要做的事情以及具体事项的具体情况,有两种选择。

The first is Rob W's solution, which should redirect the user from /category?category=News to /categorysearch/result/?q=News 第一个是Rob W的解决方案,它应该将用户从/category?category=News重定向到/categorysearch/result/?q=News

If, as it appears, your URLs are case-sensitive, you might want to look at a PHP script like the following: 如果看起来像您的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
}

Once that's settled, you can use a rule like the following to redirect using a fully lowercase parameter. 一旦确定,您可以使用类似以下的规则来使用完全小写的参数进行重定向。

RewriteRule ^category\?category=(.+)$ redirect.php [L]

Put together, this solution would redirect /category?category=News to /categorysearch/result/?q=news 放在一起,这个解决方案会重定向/category?category=News to /categorysearch/result/?q=news

I think 我认为

RewriteRule ^/category?category=(.*) /categorysearch/result/?q=news

Will do it. 会做的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM