Centos

網站根目錄的 URL 重寫

  • November 25, 2020

這是我在 Centos 8 上的 Apache 2.4.37 網路伺服器的配置。

文件/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>

文件/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>

第二個規則塊取自這裡並將所有 URL 重寫https://mysite.com/anypage.phphttps://mysite.com/anypage/,隱藏 PHP 文件副檔名並使永久連結更好看。

在註意到連結中建議的解決方案有一個錯誤之後,我添加了第一個規則塊——也就是說,URLhttps://mysite.com/返回了一個未找到的文件。現在它起作用了。

但是,一個小煩惱是https://mysite.com/重定向到https://mysite.com/index/(因為它載入文件index.php)。

我的問題:如何更改此配置以使 URLhttps://mysite.com/保持不變?

在註意到連結中建議的解決方案存在錯誤後,我添加了第一個規則塊——即 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 指令中(與 in 不同.htaccess),路徑的前導斜杠也與正則表達式匹配,因此,當您向 發送請求時http://mysite.com/,規則

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

/與正則表達式匹配^(.*)/$。這意味著反向引用$1將等於一個空字元串,並且生成的路徑將是/.php您的伺服器中不存在的路徑。

簡單的解決方案是將原始程式碼放在伺服器的DocumentRoot.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:// 或其他協議指示符開頭的重寫目標被假定為文件系統路徑。

引用自:https://unix.stackexchange.com/questions/620711