我尝试在.htaccess
中编写重写规则,将除一个域以外的所有流量重定向到https。然后,如果它尝试去的文件不存在,则运行后面的最后一个块,转到loader.php
,但是如果文件存在则转到它。
这是我到目前为止的迭代之一:
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(www\.)?(korle\.tt) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
<If "-f %{DOCUMENT_ROOT} . '/'">
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /loader.php [L]
</If>
<Else>
RewriteEngine On
RewriteRule ^ /404.html [R=404,L]
</Else>
我要做的是,如果用户转到korlett.org
或korlett.net
或korelett.com
或其中的任何文件,则会重定向到https://
。但不是http://korle.tt
或指向此目录的其他域(现在未指定),他们将保留HTTP。
然后,如果文件不存在或者URL返回404,则运行:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /loader.php [L]
答案 0 :(得分:1)
然后如果没有将它发送到loader.php以检查是否存在与该片段/&#34; dir&#34;的长网址对。如果失败则提供404页面。
此404响应需要由loader.php
管理 - 即。在你的PHP脚本中。因为一旦请求传递给loader.php
(任何未映射到文件或目录的请求),.htaccess
已经有效地完成了请求,您无法再让Apache处理404响应
如果找不到loader.php
,它应该服务404
但是,这确实可以在.htaccess
中进行管理,方法是设置ErrorDocument
并删除RewriteRule
替换上的斜杠前缀(可能是无论如何,因为你已经包含了RewriteBase
指令。删除斜杠前缀可防止重写循环(从重复重写到loader.php
)。换句话说,而不是:
RewriteRule ^.*$ /loader.php [L]
应该是这样的:
RewriteRule ^ loader.php [L]
正则表达式^
与此示例中的^.*$
具有相同的净结果,并且仅用于匹配任何(就像您在HTTP到HTTPS重定向中一样)。
这可以防止重写循环,因为当重写为loader.php
(相对路径,没有斜杠前缀)时,重写引擎会检测到您正在重写相同的URL并阻止进一步的重写。允许提供Apache 404 ErrorDocument
。 (而/loader.php
在技术上是一个不同的URL - 就mod_rewrite而言 - 所以重写将继续。)
因此,您的完整.htaccess
文件将变为:
ErrorDocument 404 /404.html
RewriteEngine on
RewriteBase /
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(www\.)?(korle\.tt) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ loader.php [L]
防止重写循环的另一种方法是包含loader.php
的特定异常。实际上,这可以与上面一起使用,以便尽早使重写失败,而不是等待重写引擎检测到无变化。例如,将上面的最后一个块更改为:
RewriteRule ^loader\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ loader.php [L]