网站根目录的 URL 重写

网站根目录的 URL 重写

This is the configuration of my Apache 2.4.37 webserver on Centos 8.

File /etc/httpd/conf.d/mysite.conf:

<VirtualHost *:80>

    ServerName mysite.com
    DocumentRoot "/var/www/html"

    RewriteEngine on

    RewriteCond %{SERVER_NAME} =mysite.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

File /etc/httpd/conf.d/mysite-ssl.conf:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName mysite.com
    DocumentRoot "/var/www/html"

    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/mysite.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mysite.com/privkey.pem

    ErrorDocument 403 /error403.html
    ErrorDocument 404 /error404.html
    ErrorDocument 405 /error405.html
    ErrorDocument 500 /error500.html

    RewriteEngine on

    # First rule block
    RewriteRule ^/$ /index.php [R,L]

    # Second rule block    
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(([^/]+/)*([^/.]+))\.php[\ ?]
    RewriteRule \.php$ /%1/ [R=301,NC,L]
    RewriteRule ^(.*)/$ /$1.php [NC,L]

    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

    TraceEnable off
</VirtualHost>
</IfModule>

The second rule block is taken from here and rewrites all URLs https://mysite.com/anypage.php to https://mysite.com/anypage/, hiding PHP file extensions and making permalinks nicer to see.

I've added the first rule block after noticing that the solution suggested in the link had a bug -- that is, URL https://mysite.com/ returned a File not Found. Now it works.

However, a minor annoyance is that https://mysite.com/ redirects to https://mysite.com/index/ (since it loads the file index.php).

My question: How can this configuration be changed so that the URL https://mysite.com/ stays the same?

答案1

在注意到链接中建议的解决方案有一个错误(即 URL)后,我添加了第一个规则块https://mysite.com/ 返回未找到文件。现在可以了。

我认为这并不是一个真正的错误。您提取的代码这里旨在在.htaccess文件中使用,而不是在 VirtualHost 指令中使用。事实证明RewriteRule 在 .htaccess 文件中的工作方式与在 VirtualHost 指令中的工作方式并不完全相同,这就是导致一些问题的原因。

我们看一下原来的代码:

RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(([^/]+/)*([^/.]+))\.php[\ ?]
RewriteRule \.php$ /%1/ [R=301,NC,L]
RewriteRule ^(.*)/$ /$1.php [NC,L]

在 VirtualHost 指令中(与 中不同.htaccess),路径的前导斜杠也会与正则表达式匹配,因此,当您向 发送请求时http://mysite.com/,规则

 RewriteRule ^(.*)/$ /$1.php [NC,L]

/与正则表达式匹配^(.*)/$。这意味着反向引用$1将等于空字符串,并且生成的路径将是/.php您的服务器中不存在的路径。

简单的解决方案是将原始代码放在一个.htaccess文件中文档根目录您的服务器的目录(即包含所有公共文件的目录)。

但是,如果您想将 RewriteRules 保留在 VirtualHost 指令中(不推荐),您可以通过在前面添加斜杠来稍微修改原始代码:

RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(([^/]+/)*([^/.]+))\.php[\ ?]
RewriteRule \.php$ /%1/ [R=301,NC,L]
RewriteRule ^/(.*)/$ /$1.php [NC,L]

现在,当向 发送请求时http://mysite.com/,Apache 将尝试匹配/但未^/(.*)/$成功,因此 URL 将保持不变。另一方面, 的请求将与http://mysite.com/foo/匹配,将其映射到所需的结果。/foo/^/(.*)/$/foo.php

,请记住,当您未在 RewriteRule 中指定完整的目标 URL 时,Apache 会假定它来自服务器的本地文件系统(而不是 DocumentRoot):

不以 http:// 或其他协议指示符开头的重写目标被假定为文件系统路径。

答案2

我通过更改主页的所有内部链接解决了我的问题

https://mysite.com/index.php 

https://mysite.com/  

相关内容