[英]Mod-Rewrites Not Working in htaccess with PHP
我已经从我的其他站点复制了 htaccess 文件(它们都可以工作,并且在同一台服务器上)并且只更改了需要更改的 URL(即从非 www 重定向到 www 时),但它根本不起作用。
例如,我将/index.php
为/index
失败,但/example.html
确实在/example
工作,这让我认为这是 PHP 或 htaccess 与 PHP 一起工作的问题?
我已经请我的几个朋友看一看,但他们不明白为什么会这样。
我的 .htaccess 文件是:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.example.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [NC,L]
我的 VirtualHost 是:
<VirtualHost *:443>
ServerName example.com
ServerAlias localhost
DocumentRoot "/var/www/example.com/public_html"
<Directory "/var/www/example.com/public_html">
Options +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
ServerAlias localhost
DocumentRoot "/var/www/example.com/public_html"
<Directory "/var/www/example.com/public_html">
Options +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com [OR]
RewriteCond %{SERVER_NAME} =localhost
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
ServerAlias localhost
DocumentRoot "/var/www/example.com/public_html"
<Directory "/var/www/example.com/public_html">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
<VirtualHost *:80>
ServerName www.example.com
ServerAlias localhost
DocumentRoot "/var/www/example.com/public_html"
<Directory "/var/www/example.com/public_html">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.example.com [OR]
RewriteCond %{SERVER_NAME} =localhost
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
(我已经用 example.com 替换了域——它们与 htaccess 或 vhost 中的不同。)
.htaccess 当然没有被禁用,如果我进行重定向它就可以正常工作,例如:
Redirect 301 /test https://example.com/test
和...
root@server:~# a2enmod rewrite
Module rewrite already enabled
我以前从未在我的网络服务器上遇到过任何类似的问题,我真的很困惑为什么会出现这个问题。
您实际上并未说明发生了什么(错误?响应代码?等),但是,您的配置在无扩展名 URL 方面存在一些问题。
Options +Indexes +Includes +FollowSymLinks +MultiViews
您在服务器配置中明确启用了MultiViews
,但是,这将与.htaccess
中试图附加文件扩展名的 mod_rewrite 指令发生冲突。 需要禁用MultiViews
。 例如。 -MultiViews
(不是+
)。
但是,出于某种原因,您还启用了目录索引 ( Indexes
) 和服务器端包含 ( Includes
)? 这是故意的吗? 而且,相当令人困惑的是,您为 www 子域设置了与域顶点不同的选项?
在 vHost 容器中,通常最好仅说明所需的选项。 例如:
Options FollowSymLinks
(这自然会通过不设置来禁用 MultiViews。)
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\\.php -f RewriteRule ^(.*)$ $1.php [NC,L]
.htaccess
用于附加文件扩展名的这些 mod_rewrite 指令并不严格正确。 虽然它们可能适用于您的“有效”URL,但恶意用户可以构建一个/index/<anything>
形式的 URL,否则将映射到/index.php
,以触发重写循环(500 内部服务器错误) * 1 .
这些应该这样写(假设你的.htaccess
文件在文档根目录中)以避免这个漏洞:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule (.*) $1.html [L]
文字点不需要在TestString ( RewriteCond
指令的第一个参数)中转义,因为这是一个“字符串”,而不是正则表达式。 此处不需要NC
标志。
如果您的 URL 本身不包含“文件扩展名”,那么您可以通过不测试看起来已经具有文件扩展名的 URL 来优化上述内容。 例如:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}.php [L]
否定的正则表达式!\\.\\w{2,4}$
仅匹配不包含 - 看起来像 - 文件扩展名的 URL。 此上下文中的文件扩展名是 URL 路径末尾的 2 到 4 个字母/数字序列,前面是一个点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.