Regex htaccess的行为与预期不符

Regex htaccess的行为与预期不符,regex,apache,.htaccess,redirect,mod-rewrite,Regex,Apache,.htaccess,Redirect,Mod Rewrite,我正在创建一个htaccess,我想通过它实现三件事: 删除尾部斜杠 将所有不是css、ico、jpg、js、php或png文件的请求重定向到index.php 如果查询字符串不是以a开头,请将所有文件重定向到view.php 现在看起来是这样的 RewriteEngine On RewriteBase /test/ RewriteRule ^(.*)/$ $1 [N] # remove trailing slash Rew

我正在创建一个htaccess,我想通过它实现三件事:

  • 删除尾部斜杠
  • 将所有不是
    css
    ico
    jpg
    js
    php
    png
    文件的请求重定向到index.php
  • 如果查询字符串不是以
    a开头,请将所有文件重定向到view.php
现在看起来是这样的

RewriteEngine On
RewriteBase /test/
RewriteRule ^(.*)/$ $1 [N]                                  # remove trailing slash

RewriteCond %{REQUEST_URI} !\.(css|ico|jpg|js|php|png)$     # if it isn't one of the files
RewriteRule . "index.php" [L]                               # then redirect to index

RewriteCond %{QUERY_STRING} !^a($|&)                        # if query doesn't start with a
RewriteRule . "view.php" [L]                                # then redirect to view
这样,以下测试用例应该是正确的:

http://127.0.0.1/test/contact               ->         http://127.0.0.1/test/index.php
http://127.0.0.1/test/contact/              ->         http://127.0.0.1/test/index.php
http://127.0.0.1/test/contact.png           ->         http://127.0.0.1/test/view.php
http://127.0.0.1/test/contact.png?a         ->         http://127.0.0.1/test/contact.png?a
当我在上尝试这些时,它会准确地显示这些结果。
然而,在实践中,当我尝试URL时,它会完全中断:

http://127.0.0.1/test/contact               ->         http://127.0.0.1/test/view.php
http://127.0.0.1/test/contact/              ->         Error 500
http://127.0.0.1/test/contact.png           ->         http://127.0.0.1/test/view.php
http://127.0.0.1/test/contact.png?a         ->         http://127.0.0.1/test/contact.png?a
脚本似乎总是首先查看与查询相关的部分,尽管考虑到这一点,
/contact/
中断对我来说仍然没有多大意义。但是,当我删除与查询相关的部分时,其余部分就可以工作了

我忘了什么吗?我不知道有没有关于操作顺序的规定?我打错了吗

所有的输入是感激的


p.S.我知道我必须为所有本地图像、样式表、脚本和AJAX调用添加一个以
a
开头的查询。我这样做是为了,当人们在单独的选项卡中查看媒体时,我可以围绕它创建一个奇特的页面,允许人们浏览服务器上公开的所有媒体。

代码问题:

  • 首先,所有非css/js/image请求都被路由到
    index.php
    ,然后没有
    ?a
    的任何请求都被路由到
    view.php
    ,因此最终根本不会使用
    index.php
    。对于没有
    .php
    扩展名的任何内容,都需要在上一条规则中使用否定条件
  • mod_rewrite
    语法不允许内联注释
  • 您需要在第一条规则中使用
    R
    标志来更改浏览器中的URL
  • 您可以在
    /test/.htaccess
    中使用此代码:

    RewriteEngine On
    RewriteBase /test/
    
    # if not a directory then remove trailing slash
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)/$ $1 [L,NE,R=301]
    
    RewriteCond %{REQUEST_URI} !\.(css|ico|jpe?g|js|php|png)$
    RewriteRule . index.php [L]
    
    RewriteCond %{QUERY_STRING} !(^|&)a [NC]
    RewriteRule !\.php$ view.php [L,NC]
    

    您可以为重写模块(对于apache 2.2,对于apache 2.4)启用并发布调试日志吗?它现在可以工作了,但在文件相关部分中使用L标志时,如何读取查询相关部分?
    L
    标志不会停止执行其他规则。它只会导致
    mod_rewrite
    循环再次运行。(它在
    循环中作为
    继续
    ,而
    循环不是
    中断
    )被接受,因为您完美地解决了问题。如果你不介意的话,我还有一个问题。将
    R
    标志添加到尾部斜杠规则不会更新浏览器的URL。你们知道为什么吗?
    RewriteRule^(+)/$$1[L,R]
    肯定会更改浏览器中的URL。让我知道你是否需要这样做,我会更新答案。因为之前我对
    L
    标志所做的假设,我想我必须把它公布出来。编写
    RewriteRule^(+)/$$1[L,R]
    确实可以让它工作,所以您可以更新它