htaccess重写规则,如果文件存在,则转到PHP文件

时间:2017-10-10 19:44:40

标签: apache .htaccess mod-rewrite

我尝试在.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.orgkorlett.netkorelett.com或其中的任何文件,则会重定向到https://。但不是http://korle.tt或指向此目录的其他域(现在未指定),他们将保留HTTP。

然后,如果文件不存在或者URL返回404,则运行:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /loader.php [L]

1 个答案:

答案 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]