重写动态网址

我试图将1个动态网址重写为另一个动态网址,如下所示;

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

捕获所有内容?category =在可用于RewriteRule的变量%1中。 但是QUERY_STRING参数有几个问题,让我们尝试一下:

  • 此参数尚未对url进行解码
  • 类别可能不是参数列表中的第一个参数
  • 甚至可能不是最后一个(&foo = bar)
  • 你之前可能有一些空间
  • 编辑

    我的第一个回答是:

    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]
    

    匹配'类别'参数,删除^允许将该参数放置在任何地方。 但是这也会匹配名为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的'='字符。 我可以使用[=|%3D]%3D在这种情况下不能很好地匹配,我不明白为什么(mod_rewrite是一块奇怪的东西)。 由于使用了第一个匹配的括号,我们必须使用%2变量而不是%1。

    然后我们有很好的([^&]+)这意味着什么,但不是'&'。

    在这些条件之后,我们应用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(这里已经被破坏)混合。 你甚至可能甚至没有在你的参数或额外属性中编码url的问题,但这很有趣:-)


    根据你想要做什么以及具体事情需要做什么,有两种选择。

    第一个是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

    会做的。

    链接地址: http://www.djcxy.com/p/55411.html

    上一篇: Rewriting dynamic URLs

    下一篇: Strategy to find duplicate entries in a binary search tree