简体   繁体   English

Mod-Rewrites 无法在 htaccess 中使用 PHP

[英]Mod-Rewrites Not Working in htaccess with PHP

I have copied the htaccess file from my other sites (that all work, and are on the same server) and have only changed URLs that need changing (ie when redirecting from non-www to www), but it simply does not work.我已经从我的其他站点复制了 htaccess 文件(它们都可以工作,并且在同一台服务器上)并且只更改了需要更改的 URL(即从非 www 重定向到 www 时),但它根本不起作用。

My changing of, for example, /index.php to /index fails, but /example.html does work at /example , which makes me think it's an issue with PHP or htaccess acting with PHP?例如,我将/index.php/index失败,但/example.html确实在/example工作,这让我认为这是 PHP 或 htaccess 与 PHP 一起工作的问题?

I've asked several friends of mine to have a look at it and they cannot understand why it's happening.我已经请我的几个朋友看一看,但他们不明白为什么会这样。

My .htaccess file is:我的 .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] 

And my VirtualHost is:我的 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>

(I've replaced the domain with example.com -- they're not like that in htaccess or the vhost.) (我已经用 example.com 替换了域——它们与 htaccess 或 vhost 中的不同。)

.htaccess is certainly not disabled, if I make a redirect it works just fine, for example: .htaccess 当然没有被禁用,如果我进行重定向它就可以正常工作,例如:

Redirect 301 /test https://example.com/test

and...和...

root@server:~# a2enmod rewrite
Module rewrite already enabled

I've never experience any similar issues with my web-server before, and I'm really puzzled as to why the issue is occurring.我以前从未在我的网络服务器上遇到过任何类似的问题,我真的很困惑为什么会出现这个问题。

You don't actually state what is happening (errors? response codes? etc.), however, there are a few issues with your config with respect to extensionless URLs.您实际上并未说明发生了什么(错误?响应代码?等),但是,您的配置在无扩展名 URL 方面存在一些问题。

 Options +Indexes +Includes +FollowSymLinks +MultiViews

You are explicitly enabling MultiViews in your server config, however, this is going to conflict with the mod_rewrite directives in .htaccess that attempt to append the file extension.您在服务器配置中明确启用了MultiViews ,但是,这将与.htaccess中试图附加文件扩展名的 mod_rewrite 指令发生冲突。 MultiViews needs to be disabled .需要禁用MultiViews eg.例如。 -MultiViews (not + ). -MultiViews (不是+ )。

However, you are also enabling directory indexes ( Indexes ) and server-side-includes ( Includes ) for some reason?但是,出于某种原因,您还启用了目录索引 ( Indexes ) 和服务器端包含 ( Includes )? Is this intentional?这是故意的吗? And, rather confusingly, you are setting different options for your www subdomain than for the domain apex?而且,相当令人困惑的是,您为 www 子域设置了与域顶点不同的选项?

In the vHost container it is often preferable to state just the options needed.在 vHost 容器中,通常最好仅说明所需的选项。 For example:例如:

Options FollowSymLinks

(This naturally disables MultiViews by not setting it.) (这自然会通过不设置来禁用 MultiViews。)

 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\\.php -f RewriteRule ^(.*)$ $1.php [NC,L]

These mod_rewrite directives in .htaccess to append the file extension are not strictly correct. .htaccess用于附加文件扩展名的这些 mod_rewrite 指令并不严格正确。 Whilst they may work for your "valid" URLs, a malicious user could construct a URL of the form /index/<anything> that would otherwise map to /index.php , to trigger a rewrite-loop (500 Internal Server Error) *1 .虽然它们可能适用于您的“有效”URL,但恶意用户可以构建一个/index/<anything>形式的 URL,否则将映射到/index.php ,以触发重写循环(500 内部服务器错误) * 1 .

These should be written like this instead (assuming your .htaccess file is in the document root) to avoid this vulnerability:这些应该这样写(假设你的.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]

The literal dot does not need to be escaped in the TestString (first argument to the RewriteCond directive) since this is a "string", not a regex.文字点不需要在TestStringRewriteCond指令的第一个参数)中转义,因为这是一个“字符串”,而不是正则表达式。 The NC flag is not required here.此处不需要NC标志。

If your URLs themselves don't contain "file extensions" then you can optimise the above by not testing URLs that already look like they have a file extension.如果您的 URL 本身不包含“文件扩展名”,那么您可以通过不测试看起来已经具有文件扩展名的 URL 来优化上述内容。 For example:例如:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}.php [L]

The negated regex !\\.\\w{2,4}$ only matches URLs that don't contain - what looks like - file extensions.否定的正则表达式!\\.\\w{2,4}$仅匹配不包含 - 看起来像 - 文件扩展名的 URL。 A file extension in this context is a sequence of 2 to 4 letters/digits at the end of the URL-path, preceded by a dot.此上下文中的文件扩展名是 URL 路径末尾的 2 到 4 个字母/数字序列,前面是一个点。


*1 See my answer to the following ServerFault question that goes into more detail regarding the potential rewrite-loop and resulting 500 error response: *1请参阅对以下 ServerFault 问题的回答,其中详细介绍了潜在的重写循环和导致的 500 错误响应:

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

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