两个类似的网站,曾经是 Apache 实例,URL 重写对其中一个有效,但对另一个无效

两个类似的网站,曾经是 Apache 实例,URL 重写对其中一个有效,但对另一个无效

我的重写规则旨在隐藏目录结构并使 URL 更易于阅读。网站gcems按预期运行,但vigotwpfd不会加载第一页以外的文件,也不会在第一页上抛出错误。

这是我的设置:

开发平台:两个站点均按预期运行。

“实时/测试”平台:一台在 Linux 上运行 Apache 2.4 的一个实例的机器。

一个动态 IP 连接到互联网。

两个主机名,都使用 duckdns.org 作为我的动态 IP 提供商。gcems.duckdns.orgvigotwpfd.duckdns.org设置为虚拟主机。

两个网站都运行 PHP 7.x

两个站点的设置非常相似。目录结构相同。文件结构相似。两者都使用 URL 重写规则,除了指向 的 URL 规则gcems和指向 的gcems规则外,其他规则完全相同。vigotwpfdvigotwpfd

Apache 域配置文件和.htacess文件也相同,除了gcemsvs之外vigotwpfd

以下是两个域的简化目录/文件结构。

  • vigotwpfd==>/var/www/vigotwpfd
  • gcems ==>/var/www/html

/var/www/site/
|-- assets
|   |-- css
|   |   `-- view.css
|   |-- gallery
|   |   `-- blank.jpg
|   |-- htc
|   |   `-- iepngfix.htc
|   |-- images
|   |   `-- <image files>
|   `-- js
|       `-- <javascript files>
|-- classes
|   |-- Bootstrap.php
|   |-- Controller.php
|   |-- Messages.php
|   `-- Model.php
|-- controllers
|   `-- <controller files>
|-- models
|   `-- <models files>
|-- views
|   |-- <other directories and php web pages>
|   `-- main.php
|-- config.php
|-- .htaccess
`-- index.php

.htaccess

Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z]*)/?([a-zA-Z]*)?/?([a-zA-Z0-9]*)?/?$ index.php?controller=$1&action=$2&id=$3 [NC,L]
Options +FollowSymLinks
RewriteEngine on

RewriteCond %{SERVER_PORT} 80
# This checks to make sure the connection is not already HTTPS -  port 80 indicates a non-secured HTTP conection.

RewriteRule ^(.*)$ https://site.duckdns.org/$1 [R=301,L]
# This rule will redirect users from their original location to the same location but using HTTPS.

RewriteRule ^([a-zA-Z]*)/?([a-zA-Z]*)?/?([a-zA-Z0-9]*)?/?$ index.php?controller=$1&action=$2&i$

apache2/sites-enabled/gcems.duckdns.org.conf

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName gcems.duckdns.org
        ServerAlias *.gcems.duckdns.org
        DocumentRoot /var/www/html

        ErrorLog ${APACHE_LOG_DIR}/gcems_error.log
        CustomLog ${APACHE_LOG_DIR}/gcems_access.log combined
</VirtualHost>

错误信息发现vigotwpfd_error.log

[Mon Nov 05 08:33:40.101435 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP Notice:  Undefined index: controller in /var/www/vigotwpfd/classes/Bootstrap.php on line 38, referer: https://vigotwpfd.duckdns.org/
[Mon Nov 05 08:33:40.101670 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP Stack trace:, referer: https://vigotwpfd.duckdns.org/
[Mon Nov 05 08:33:40.101784 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP   1. {main}() /var/www/vigotwpfd/index.php:0, referer: https://vigotwpfd.duckdns.org/
[Mon Nov 05 08:33:40.101914 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP   2. Bootstrap->__construct() /var/www/vigotwpfd/index.php:60, referer: https://vigotwpfd.duckdns.org/
[Mon Nov 05 08:33:40.102365 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP Notice:  Undefined index: action in /var/www/vigotwpfd/classes/Bootstrap.php on line 45, referer: https://vigotwpfd.duckdns.org/
[Mon Nov 05 08:33:40.102488 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP Stack trace:, referer: https://vigotwpfd.duckdns.org/
[Mon Nov 05 08:33:40.102556 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP   1. {main}() /var/www/vigotwpfd/index.php:0, referer: https://vigotwpfd.duckdns.org/
[Mon Nov 05 08:33:40.102630 2018] [:error] [pid 2993] [client 107.77.210.136:29694] PHP   2. Bootstrap->__construct() /var/www/vigotwpfd/index.php:60, referer: https://vigotwpfd.duckdns.org/

https://github.com/pavulon18/vigotwp
https://github.com/pavulon18/gcas_timesheet_php_website

以下是我的理论:

  1. URL 重写系统存在问题
  2. Apache 配置存在问题(无论是网站vigotwpfd还是服务器本身)
  3. 我的代码乱了。

我已经通过调试器一步一步地运行vigotwpfd,但仍然找不到问题出在哪里。

补充信息和说明

在我的问题第一次迭代中,我试图通过发布我认为绝对必要的内容来节省一些空间并减少一些噪音。我将在此编辑中发布文件的全部内容。我还将回答提出的一些问题和疑虑。

问)“但您发布的错误日志似乎表明您的 URL 重写根本没有被处理?—— MrWhite”
答)这是整个情况中最大的难题之一。此设置在网站上有效gcems,但在网站上无效vigotwpfd。我正在尝试确定两者之间的区别。

Q) “您发布的文件中的指令.htaccess顺序错误,您似乎(有点)重复了主要重写?(顺便说一句,您“htaccess”在问题中提到了一个“c” - 我想这只是您问题中的一个拼写错误?)– MrWhite 昨天”
A) 我会修复您提到的重复。对于此更新,我选择保留原始内容,只是为了避免显着改变问题的前提。是的,单个“c”是一个简单的拼写错误。在您提到这个错误后,我仔细检查了文件名。

评论: MrWhite,我注意到你删除了我的PHP标签。我列出它的原因是因为错误可能出在我的PHP代码中。我提议PHP恢复该标签。

在 gcems 上:如果我输入https://gcems.duckdns.org,我得到了网站的主页,没有错误消息。如果我输入https://gcems.duckdns.org/some_random_characters,网站将显示错误信息“控制器类不存在”。我的代码捕获了错误的目录/文件请求并显示此消息而不是404 error

在 vigotwpfd 上:如果我输入https://vigotwpfd.duckdns.org,我得到了上面列出的错误消息。如果我输入https://vigotwpfd.duckdns.org/some_random_characters,我收到一个 Apache 错误“未找到。该服务器上未找到所请求的 URL /some_random_characters。”

/etc/apache2/sites-enabled/gcems.duckdns.conf

<VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that
    # the server uses to identify itself. This is used when creating
    # redirection URLs. In the context of virtual hosts, the ServerName
    # specifies what hostname must appear in the request's Host: header to
    # match this virtual host. For the default virtual host (this file) this
    # value is not decisive as it is used as a last resort host regardless.
    # However, you must set it for any further virtual host explicitly.

    ServerAdmin webmaster@localhost
    ServerName gcems.duckdns.org
    # ServerAlias *.gcems.duckdns.org
    DocumentRoot /var/www/html

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog ${APACHE_LOG_DIR}/gcems_error.log
    CustomLog ${APACHE_LOG_DIR}/gcems_access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

/etc/apache2/sites-enabled/gcems.duckdns.org.ssl.conf

<VirtualHost *:80>
        ServerName gcems.duckdns.org
        <Location />
                Redirect permanent / https://gcems.duckdns.org/
        </Location>
</VirtualHost>
<VirtualHost *:443>
        ServerAdmin [email protected]
        ServerName gcems.duckdns.org
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/gcems_error.log
        CustomLog ${APACHE_LOG_DIR}/gcems_access.log combined
        SSLEngine On
        SSLCertificateFile <directory>/fullchain.pem
        SSLCertificateKeyFile <directory>/privkey.pem
</VirtualHost>

/var/www/html/.htaccess

Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z]*)/?([a-zA-Z]*)?/?([a-zA-Z0-9]*)?/?$ index.php?controller=$1&action=$2&id=$3 [NC,L]
Options +FollowSymLinks
RewriteEngine on

RewriteCond %{SERVER_PORT} 80
# This checks to make sure the connection is not already HTTPS -  port 80 indicates a non-secured HTTP conection.

RewriteRule ^(.*)$ https://gcems.duckdns.org/$1 [R=301,L]
# This rule will redirect users from their original location to the same location but using HTTPS.

RewriteRule ^([a-zA-Z]*)/?([a-zA-Z]*)?/?([a-zA-Z0-9]*)?/?$ index.php?controller=$1&action=$2&i$

<IfModule mod_expires.c>
  ExpiresActive ON
  ExpiresDefault "access plus 1 seconds"
</IfModule>

/etc/apache2/sites-enabled/vigotwpfd.duckdns.org.conf

<VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that
    # the server uses to identify itself. This is used when creating
    # redirection URLs. In the context of virtual hosts, the ServerName
    # specifies what hostname must appear in the request's Host: header to
    # match this virtual host. For the default virtual host (this file) this
    # value is not decisive as it is used as a last resort host regardless.
    # However, you must set it for any further virtual host explicitly.

    ServerAdmin webmaster@localhost
    ServerName vigotwpfd.duckdns.org
    # ServerAlias *.vigotwpfd.duckdns.org
    DocumentRoot /var/www/vigotwpfd

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog ${APACHE_LOG_DIR}/vigo_error.log
    CustomLog ${APACHE_LOG_DIR}/vigo_access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

/etc/apache2/sites-enabled/vigotwpfd.duckdns.org.ssl.conf

<VirtualHost *:80>
    ServerName vigotwpfd.duckdns.org
    <Location />
            Redirect permanent / https://vigotwpfd.duckdns.org/
    </Location>
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName vigotwpfd.duckdns.org
#       ServerAlias *.vigotwpfd.duckdns.org
    DocumentRoot /var/www/vigotwpfd

    ErrorLog ${APACHE_LOG_DIR}/vigo_error.log
    CustomLog ${APACHE_LOG_DIR}/vigo_access.log combined

    SSLEngine On
    SSLCertificateFile /var/lib/dehydrated/certs/vigotwpfd.duckdns.org/fullchain.pem
    SSLCertificateKeyFile /var/lib/dehydrated/certs/vigotwpfd.duckdns.org/privkey.pem

</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

/var/www/vigotwpfd/.htaccess

Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z]*)/?([a-zA-Z]*)?/?([a-zA-Z0-9]*)?/?$ index.php?controller=$1&action=$2&id=$3 [NC,L]
Options +FollowSymLinks
RewriteEngine on
LogLevel alert rewrite:trace3

RewriteCond %{SERVER_PORT} 80
# This checks to make sure the connection is not already HTTPS -  port 80 indicates a non-secured HTTP conection.

RewriteRule ^(.*)$ https://vigotwpfd.duckdns.org/$1 [R=301,L]
# This rule will redirect users from their original location to the same location but using HTTPS.

RewriteRule ^([a-zA-Z]*)/?([a-zA-Z]*)?/?([a-zA-Z0-9]*)?/?$ index.php?controller=$1&action=$2&i$

<IfModule mod_expires.c>
  ExpiresActive ON
  ExpiresDefault "access plus 1 seconds"
</IfModule>

答案1

您似乎有两个<VirtualHost *:80>相同的容器ServerName(用于gcemsvigotwpfd)?其中只有一个可能成功 - 第一个在服务器配置中定义的容器(在处理包含内容之后)。因此,我怀疑从 HTTP 到 HTTPS 的重定向未在您的服务器配置中发生,这就是为什么您的.htaccess文件中有一个 mod_rewrite HTTP 到 HTTPS 的重定向。

...指令在哪里AllowOverride

AllowOverride由于您已发布整个 vHost 配置,因此您的配置中仍然没有任何指令。如果没有适当的指令,您的.htaccess重写/重定向将无法工作AllowOverride某处在您的服务器配置中(在容器中)。您收到的 PHP 错误(和 Apache 404)与 mod_rewrite 未执行任何操作<Directory>一致。.htaccess

是否http://vigotwpfd.duckdns.org重定向到 HTTPS?(我刚刚检查过 - 没有)这进一步表明.htaccess/mod_rewrite 没有执行任何操作。

现在,您还没有AllowOverride针对任何主机的指令,但“运行正常”。您的主服务器配置中gcems可能有一个零散的容器,它为 启用了此功能,但为 却没有?无论哪种方式,这都应该在 vHost 中定义,而不是在主服务器配置中定义。<Directory /var/www/html>gcems/var/www/vigotwpfd

PHP 通知:未定义索引:控制器在...

如果重写已处理,.htaccess那么您将不会收到此“PHP 通知”,因为 $_GET['controller']始终会定义。(我猜您一定是在 PHP 代码的某个地方提到了这一点?)但是,您的 PHP 代码应该始终检查 URL 参数是否存在,如果不存在则默认。因此,在任何情况下您都不应该看到此 E_NOTICE。

相关内容