繁体   English   中英

Mod-Rewrites 无法在 htaccess 中使用 PHP

[英]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]

文字点不需要在TestStringRewriteCond指令的第一个参数)中转义,因为这是一个“字符串”,而不是正则表达式。 此处不需要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 个字母/数字序列,前面是一个点。


*1请参阅对以下 ServerFault 问题的回答,其中详细介绍了潜在的重写循环和导致的 500 错误响应:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM