我正在开发一个MVC项目,我有以下.htaccess
文件:
Options -Indexes
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?path=$1 [L]
RewriteRule !^(public/|index\.php) [NC,F]
一切正常。我只希望公众可以访问public/
文件夹和index.php
文件。应将所有其他路径插入path
GET参数。例如,mysite.com/controller/method
应指向mysite.com/index.php?path=controller/method
。
现在,有一个问题。在直接访问网址时(不包括index.php
),它会将[NC,F]
添加到GET path
参数中。就像访问mysite.com
指向mysite.com/index.php?path=[NC,F]
一样。< / p>
为什么会发生这种情况,我该如何解决?
修改
我将index.php
移到public/
文件夹中。现在是我的.htaccess
文件:
Options -Indexes
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
RewriteRule ^(/)?$ public/index.php [L]
RewriteRule !^(public/) [NC,F]
似乎工作正常。我可以对此做出任何其他改进吗?
答案 0 :(得分:1)
您在最后一条规则上没有重定向位置,因此它将标记作为重定向位置。只需要一个破折号即可,因为这是一个禁止的回应。将最后一行更改为:
RewriteRule !^(public/|index\.php$) - [NC,F]
在index.php之后添加美元符号只是为了清楚。
修改强>
我建议将您的新规则集更新为以下内容(实际上我建议在下面进行完整的重新思考,但这是对您所拥有内容的更新):
RewriteEngine On
RewriteRule ^$ public/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
RewriteRule !^(public/) - [NC,F]
主页规则中不需要(/)?
,因为前面的正斜杠不会包含在.htaccess
匹配中。
我将主页的规则移到了顶部,或者由于与之前的规则匹配而永远不会被使用(因此当空的时候路径参数不存在,这可能是你想要的)。
我阻止/ public /中的任何内容被传递给你的index.php脚本,因为你拥有它的方式,公开的任何不存在的东西都会传递给你的索引脚本,这似乎不是你打算做什么。
我添加了RewriteCond %{REQUEST_URI} !=/public/index.php
所以规则无法自行执行并创建一个循环,如果规则处理不止一次运行,它可以,但随后将其取回,因为上面的匹配无论如何,/ public /涵盖了这一点。
重新思考
所有这一切,我认为检查文件是否不存在然后只是发送禁止的响应,然后将其他所有内容发送到您的索引脚本是不正确的。为什么不将所有内容发送到索引脚本?这似乎是你真正想要的。我建议你简化一下:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
删除主页规则,因为无需担心传递给索引脚本的空路径参数。将逻辑更改为“将任何内容保留在/ public / alone。对于其他任何内容,将其传递给index.php脚本。”所以文件测试不需要,因为脚本会处理所有文件,并且不需要禁止响应,因为没有什么可以匹配,它们都被规则所覆盖。您可以随时返回禁止在脚本中处理的任何内容,无论如何,您需要为之前设置中的现有文件URL进行此操作。
最后一次重新思考
最后,如果我可以建议,将index.php文件放在网站的根目录中会更加清晰,所以如果你愿意,可以稍后使用自己的索引文件进行/ public / work,所以最后我将它移回根并将规则更改为:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule ^(.*)$ index.php?path=$1 [L]
如果你喜欢这一切,那么已经接受答案的投票将非常感激。 :)
答案 1 :(得分:0)
添加RewriteRule ^(/)?$ public/index.php [L]
似乎解决了这个问题。我不确定这是否是最佳方法,但现在这是我的.htaccess
文件:
Options -Indexes
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/index.php?path=$1 [L]
RewriteRule ^(/)?$ public/index.php [L]
RewriteRule !^(public/) [NC,F]
我将index.php
移动到公共文件夹中以使事情变得更清晰。