【问题标题】:Why does RewriteRule x y.php succeed, but RewriteRule x y.php/foo fail?为什么 RewriteRule x y.php 成功,但 RewriteRule x y.php/foo 失败?
【发布时间】:2020-12-04 23:39:00
【问题描述】:

我正在使用现有的 .htaccess 文件对 Web 应用程序进行 dockerizing。在安装了 Apache 的 debian:stretch 中运行应用程序时,我遇到了 RewriteRules 的问题。

我把它归结为一个可以在这里说明的问题:

RewriteRule ^works$    /symfony/web/json.php       [QSA,L]
RewriteRule ^fails$    /symfony/web/json.php/user  [QSA,L]

第一个 RewriteRule 将用户发送到 symfony/web/json.php,这是 Symfony 1 项目中的一个文件,在那里他们得到了由 Symfony 处理的适当 404。

第二个RewriteRule 不会将用户发送到 Symfony 领域,通常会将尾随的“/user”交给控制器来处理。我只是得到一个“找不到文件”。

相反,看起来更深目录中的 .htaccess 删除了路径的开头并将“/user”发送回根目录中的 .htaccess。

目录结构

root/
├── symfony/
│   ├── web/
│   │   ├── .htaccess
│   │   └── json.php
│   ├── .htaccess
└── .htacces

.htaccesses

root/.htaccess(相关位):

RewriteEngine On
RewriteBase /
RewriteRule ^works$    /symfony/web/json.php       [QSA,L]
RewriteRule ^fails$    /symfony/web/json.php/user  [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /symfony/web/index.php [QSA,L]

root/symfony/.htaccess(整个):

RewriteEngine On
RewriteRule ^(.*)$ /symfony/web/$1 [L]

root/symfony/web/.htaccess(相关位):

RewriteEngine On
RewriteBase /symfony/

RewriteCond %{REQUEST_URI} ^(/symfony/admin.php)
RewriteCond %{REMOTE_ADDR} !^10\.0
RewriteCond %{REMOTE_ADDR} !^10\.50
RewriteCond %{REMOTE_ADDR} !^10\.60
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1$
RewriteCond %{REMOTE_ADDR} !^::1$
RewriteRule .* / [L,R=403]

# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f

# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]

重写日志

为了调试,我设置了LogLevel debug rewrite:trace3。以下是尝试转到 /fail 时日志中的相关位:

[rewrite:trace3] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] strip per-dir prefix: /home/wwwroot/root/fails -> fails
[rewrite:trace3] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] applying pattern '^works$' to uri 'fails'
[rewrite:trace3] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] strip per-dir prefix: /home/wwwroot/root/fails -> fails
[rewrite:trace3] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] applying pattern '^fails$' to uri 'fails'
[rewrite:trace2] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] rewrite 'fails' -> '/symfony/web/json.php/user'
[rewrite:trace2] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] trying to replace prefix /home/wwwroot/root/ with /
[rewrite:trace2] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] trying to replace context docroot /home/wwwroot/root with context prefix 
[rewrite:trace1] [rid#7f8c7807d0a0/initial] [perdir /home/wwwroot/root/] internal redirect with /symfony/web/json.php/user [INTERNAL REDIRECT]
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] add path info postfix: /home/wwwroot/root/symfony/web/json.php -> /home/wwwroot/root/symfony/web/json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] strip per-dir prefix: /home/wwwroot/root/symfony/web/json.php/user -> json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] applying pattern '.*' to uri 'json.php/user'
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] add path info postfix: /home/wwwroot/root/symfony/web/json.php -> /home/wwwroot/root/symfony/web/json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] strip per-dir prefix: /home/wwwroot/root/symfony/web/json.php/user -> json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] applying pattern '^$' to uri 'json.php/user'
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] add path info postfix: /home/wwwroot/root/symfony/web/json.php -> /home/wwwroot/root/symfony/web/json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] strip per-dir prefix: /home/wwwroot/root/symfony/web/json.php/user -> json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] applying pattern '^([^.]+)$' to uri 'json.php/user'
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] add path info postfix: /home/wwwroot/root/symfony/web/json.php -> /home/wwwroot/root/symfony/web/json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] strip per-dir prefix: /home/wwwroot/root/symfony/web/json.php/user -> json.php/user
[rewrite:trace3] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] applying pattern '^(.*)$' to uri 'json.php/user'
[rewrite:trace1] [rid#7f8c7805c4a8/initial/redir#1] [perdir /home/wwwroot/root/symfony/web/] pass through /home/wwwroot/root/symfony/web/json.php
[rewrite:trace3] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] strip per-dir prefix: /home/wwwroot/root/user -> user
[rewrite:trace3] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] applying pattern '^works$' to uri 'user'
[rewrite:trace3] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] strip per-dir prefix: /home/wwwroot/root/user -> user
[rewrite:trace3] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] applying pattern '^fails$' to uri 'user'
[rewrite:trace3] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] strip per-dir prefix: /home/wwwroot/root/user -> user
[rewrite:trace3] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] applying pattern '^(.*)$' to uri 'user'
[rewrite:trace2] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] rewrite 'user' -> '/symfony/web/index.php'
[rewrite:trace2] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] trying to replace prefix /home/wwwroot/root/ with /
[rewrite:trace2] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] trying to replace context docroot /home/wwwroot/root with context prefix 
[rewrite:trace1] [rid#7f8c780830a0/subreq] [perdir /home/wwwroot/root/] internal redirect with /symfony/web/index.php [INTERNAL REDIRECT]

所以它看起来像在根 .htaccess 中,RewriteRule ^fails$ /symfony/web/json.php/user 匹配并将请求重定向到 symfony/web/ 中的 .htaccess,它找到匹配但剥离 url 的开头,将“/user”发送回原始根 .htaccess。

【问题讨论】:

  • 您的第一个重定向将请求发送到symfony/web/json.php,就像您说的一个文件。然后您的第二个重定向将请求发送到symfony/web/json.php/user。从 Apache 的角度来看,这没有任何意义,因为您正在转发到 directory/directory/FILE/directory。要使此规则起作用,应该有一个名为symfony/web/json.php/user 的目录链。你看? json.php 应该是一个目录!如果你想为json.php 指定参数,它应该使用GET 语句语法,例如json.php?user=something 或类似的语法。
  • @Nic3500 使用路径信息后缀(匹配文件之外的部分,在这种情况下为/user)是有效的,并且是 Symfony 用来决定调用哪个路由/控制器的。此外,当我在浏览器中直接访问symfony/web/json.php/user 时,它会提供正确的页面。只是 RewriteRules 让我失望了。
  • 这就是我所说的“从 Apache 的角度来看”。很抱歉,我无法进一步帮助与 Symfony 的交互。

标签: apache docker .htaccess mod-rewrite symfony1


【解决方案1】:

问题是由 Apache 版本引起的。

我的 Apache 容器使用的是 debian:stretch Docker 映像,其中包括 Apache 2.4.25。我将基础映像更改为 debian:buster,其中包括 Apache 2.4.38。该更新解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 2018-01-21
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多