I have the following .htaccess
file on my Apache Server, which does not work
我的Apache服务器上有以下.htaccess文件,该文件不起作用
<If "%{HTTP_HOST} == 'www.example.com'">
RewriteCond %{REMOTE_ADDR} !^192\.168\.8\.8$
RewriteRule .* - [F]
RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]
</If>
The code works fine without the if-Statement.
But with the if Statement
如果没有if语句,代码可以正常工作。但是使用if语句
RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]
does not work. It throws a "404 Not Found error"
不起作用。它抛出“404未找到错误”
更多回答
Are you sure you test for the right value here www.somehost.com
? Did you try for example with another IP address than 192.168.8.8
to test for the 403 forbidden (assuring that the if condition is properly evaluated)?
你确定在www.somehost.com测试正确的值吗?例如,您是否尝试使用192.168.8.8以外的另一个IP地址来测试403禁用(确保正确评估if条件)?
Why the if
command? Why don't you another rewrite condition for that? RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$
为什么使用if命令?你为什么不换一个重写条件呢?重写结束%{HTTP_HOST}^(www\.)?示例\.com$
<If "%{HTTP_HOST} == 'www.example.com'">
RewriteCond %{REMOTE_ADDR} !^192\.168\.8\.8$
RewriteRule .* - [F]
RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]
</If>
The "problem" is because the mod_rewrite directives are embedded inside an <If>
expression. <If>
blocks are merged very late, after the request has been mapped back to the file system. In this context, the RewriteRule
pattern matches against the absolute filesystem path, not a relative URL-path, so the second rule above will not match as expected.
“问题”是因为mod_rewrite指令嵌入在
表达式中<如果>块在请求映射回文件系统后很晚才合并。在这种情况下,RewriteRule模式与绝对文件系统路径匹配,而不是与相对URL路径匹配,因此上面的第二条规则将不会像预期的那样匹配。
So, the rule would need to be rewritten like this instead:
因此,该规则需要像这样重写:
RewriteRule ^/abs/file/path/to/docroot/([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
Or, more simply, remove the start-of-string anchor - although this does make the match somewhat ambiguous:
或者,更简单地说,删除字符串锚的开头——尽管这确实会使匹配变得有些模糊:
RewriteRule /([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
Or, preferably, avoid the <If>
construct altogether as you can get unexpected conflicts with other directives (outside of the <If>
construct). For example:
或者,最好完全避免
构造,因为您可能会与其他指令(在
构造之外)发生意外冲突。例如:
RewriteCond %{HTTP_HOST} =www.example.com
RewriteCond %{REMOTE_ADDR} !^192\.168\.8\.8$
RewriteRule ^ - [F]
RewriteCond %{HTTP_HOST} =www.example.com
RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
(The NC
flag is not necessary in the 2nd rule, since you are already matching A-Z
and a-z
in the regex. ALso, use ^
instead of .*
in the first rule, since you don't need to actually match anything here.)
(在第二条规则中不需要NC标志,因为您已经在正则表达式中匹配A-Z和A-Z。因此,在第一条规则中使用^而不是.*,因为您实际上不需要在这里匹配任何内容。)
If you have many such rules that apply to just this one host then you can reverse the logic and skip the N rules that follow when the requested host is not what is expected. For example:
如果您有许多这样的规则仅适用于这一台主机,那么当请求的主机不是预期的主机时,您可以颠倒逻辑,跳过后面的N条规则。例如:
# Skip the next 2 rules if the requested host is not "www.example.com"
RewriteCond %{HTTP_HOST} !=www.example.com
RewriteRule ^ - [S=2]
RewriteCond %{REMOTE_ADDR} !^192\.168\.8\.8$
RewriteRule ^ - [F]
RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [L]
I came myself to the following solutiuon. which i really like.
我自己找到了以下解决方案。我真的很喜欢。
### Access control
###
###
# Set the environment variable if the HTTP_HOST matches 'www.somehost.com'.
SetEnvIf Host "www\.somehost\.com" IS_HOST=true
# Use the set environment variable in a conditional
RewriteCond %{ENV:IS_HOST} true
RewriteCond %{REMOTE_ADDR} !^192\.168\.8\.8$
RewriteRule .* - [F]
### Rewrite Urls
###
###
RewriteRule ^([A-Za-z0-9_-]+)$ index.php?p=$1 [NC,L]
更多回答
我是一名优秀的程序员,十分优秀!