代码之家  ›  专栏  ›  技术社区  ›  ArtOfCode

如何将子目录重定向到目录和查询字符串?

  •  1
  • ArtOfCode  · 技术社区  · 9 年前

    我正在尝试使用.htaccess和mod_rewrite重定向网站上的URL。

    我想要这样 /questions/12345 /users/12345 重定向到 /questions/display.php?id=12345 /users/display.php?id=12345 分别地

    我愿意 而且 喜欢添加快捷方式,有点像Stack Exchange /q/12345/6789 被重写为 /questions/display.php?id=12345&refer=6789 .

    到目前为止 several sources ,我有这个:

    RewriteEngine On
    RewriteRule ^users/([^/]+) /users/display.php?id=$1 [NC]
    RewriteRule ^questions/([^/]+) /questions/display.php?id=$1 [NC]
    RewriteRule ^q/([^/]+)/([^/]+) /questions/display.php?id=$1&referer=$2 [NC]
    

    然而,当我导航到 /问题/1245 ,我收到一个500内部服务器错误-很明显,这不起作用。

    在查看Apache错误日志时,它揭示了发生的情况:

    AH00124:由于可能的配置错误,请求超过了10个内部重定向的限制。如有必要,请使用“LimitInternalRecursion”增加限制。使用“LogLevel debug”获取回溯。

    这里出了什么问题 应该 我做到了?

    2 回复  |  直到 9 年前
        1
  •  2
  •   Amit Verma    9 年前

    问题是重写引擎循环,因此您重写的内容最终会再次匹配相同的规则。您可以尝试添加一些条件来防止这种情况:

    RewriteEngine On
    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^users/([^/]+) /users/display.php?id=$1 [NC,L]
    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^questions/([^/]+) /questions/display.php?id=$1 [NC,L]
    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^q/([^/]+)/([^/]+) /questions/display.php?id=$1&referer=$2 [NC,L]
    
        2
  •  1
  •   ghoti    9 年前

    您的重定向正在捕获自身。:-)

    注意正则表达式原子 ([^/]+) 。这意味着“一个或多个非正斜杠字符的任何运行”。文本 display.php?id= 匹配,所以在您的第一次请求

    /users/123
    

    您将被改写为

    /users/display.php?id=123
    

    但重定向并不止于此。新的URL还将通过重写引擎,以写入:

    /users/display.php?id=display.php?id=123
    

    重写后的URL会不断被重写,直到达到限制,如日志中所述。

    要解决这个问题,可以使初始正则表达式更具限制性。

    RewriteRule ^users/([0-9]+) /users/display.php?id=$1 [NC]
    

    您还可以告诉重写引擎特定的规则是“Last”规则,因此它不会重新处理该行(或通过任何其他规则运行该行):

    RewriteRule ^users/([0-9]+) /users/display.php?id=$1 [NC,L]
    

    最后,如果请求的路径指向文件,您可以通过告诉Apache不要应用重写规则来添加额外的保护:

    # Exempt requests to directories...
    RewriteCond %{REQUEST_FILENAME} !-d
    
    # Exempt requests directly to files...
    RewriteCond %{REQUEST_FILENAME} !-f
    
    # Rewrite /users/###
    RewriteRule ^users/([0-9]+) /users/display.php?id=$1 [NC,L]
    

    这是一个有点像腰带、背带裤和更性感的解决方案,但你想以任何可能的方式施加保护的想法是一个不错的主意。