我正在使用Apache 2.4,并设置了两个虚拟目录。一个需要SSL,另一个需要重定向到它。

如果用户尝试在不存在/ derp的情况下访问https://www.derp.com/derp,则他们会正确获取404。但是,当用户访问http://www.derp.com/derp时,Apache会将用户错误地重定向到https://www.derp.comderp,从而删除了路径和域名之间的斜杠。

我不知道是什么原因造成的。

以下是我的虚拟主机的设置。

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName www.derp.com
    ServerAlias derp.com
    DocumentRoot "C:\Users\derp\Documents\Web Projects\derp"
    SSLEngine on
    SSLCertificateFile "C:\Apache24\certs\cert.cer"
    SSLCertificateKeyFile "C:\Apache24\certs\key.key"
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName www.derp.com
    ServerAlias derp.com
    Redirect permanent / https://www.derp.com/
</VirtualHost>

<Directory "C:\Users\derp\Documents\Web Projects\derp">
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All
    Require all granted
    SSLRequireSSL
</Directory>

为什么Apache会有这种行为?

额外的问题:应该在我的虚拟主机定义中处理重定向,还是应该在网站的物理目录中的.htaccess文件中处理重定向?

编辑:

我正在启动一个Laravel项目,默认情况下,公共(public)文件夹中确实包含一个.htaccess文件,所以这是那个家伙:
<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

编辑二:

我试过了:
  • 在DirectoryRoot路径
  • 的末尾添加一个斜杠
  • 用DirectoryRoot路径
  • 中的正斜杠替换反斜杠
  • 用DirectoryRoot路径
  • 中的双反斜杠替换反斜杠

    我还从目录中完全删除了.htaccess文件。

    http://www.derp.com转到https://www.derp.com时,它可以正确重定向。仅当您指定路径并尝试使用https时,它才会删除域和路径之间的斜杠。

    编辑三:

    我还尝试了以下建议:



    ...而不是重定向到https://www.derp.comderp,而不是重定向,尝试并为http://www.derp.com/derp给出404,而是使用Apache的404,而不是像Laravel没有配置那样抛出Not Found Exception。

    编辑四:

    我也尝试过:
    <IfModule mod_rewrite.c>
        Options -MultiViews
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.php$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]
    </IfModule>
    

    在.htaccess文件中,行为完全没有改变。

    最佳答案

    我知道了。

    问题根本不在于重写,而是导致目录问题的原因是我的目录定义下的SSLRequireSSL指令。

    我只是删除了该指令,刷新了所有浏览器中的缓存,然后该站点继续正常运行。这是通过消除过程发现的。

    文档说明:



    重点是我自己的。 SSLRequireSSL如果未启用通过SSL的HTTP,则Apache可能仅返回403或404,从而干扰Redirect规则。根据您的用例,诸如this answer on Server Fault中的规则之类的重写规则可能是更好的选择:

    RewriteEngine On
    RewriteCond %{SERVER_PORT} !443
    RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/$1 [R=301,L]
    

    10-07 15:59