Apache2 重写 returns 文件扩展名
Apache2 rewrite returns filename extension
我真的不明白我哪里做错了。我正在尝试将规则应用于
http://localhost/prezzo/account/1
所以改写为
http://localhost/prezzo/account/test.php?user=1
我将 UniformServer 用作 WAMP。我将 .htaccess
文件放在我正在处理的子文件夹中 (prezzo/account/),规则如下:
RewriteEngine On
RewriteRule (\w+)/?$ test.php?user= [L]
htaccess tester 报告规则已正确应用。
但是当我转到 URL 时 http://localhost/prezzo/account/1
和 test.php
被加载 - 其中仅包含
<?php
echo $_GET['user'];
?>
它returns字符串“php”而不是“1”.
如果我尝试
RewriteRule ^prezzo/account/(\w+)/?$ prezzo/account/test.php?user= [L]
我收到 404 not found 尽管 htaccess tester 报告规则应用正确并且 URL 被重写为
http://localhost/prezzo/account/test.php?user=1
如果我在地址栏中 copy/paste 就可以了。
But when I go to the URL http://localhost/prezzo/account/1
and test.php
is loaded [...] it returns the string "php" instead of "1".
是的,发布的规则符合预期。
这似乎在“htaccess 测试器”中有效,因为该工具只对文件进行单次传递,这不是真实服务器的工作方式。
RewriteRule (\w+)/?$ test.php?user= [L]
当您请求时 /prezzo/account/1
然后...
- 请求重写为
test.php?user=1
L
标志使重写引擎使用重写的 URL (test.php?user=1
) 作为下一轮处理的输入重新开始。
- 请求被重写为
test.php?user=php
,因为正则表达式 (\w+)/?$
捕获了 test.php
的 php
部分。 (\w
shorthand 字符 class 排除了点并且正则表达式没有锚定。)
L
标志使重写引擎使用重写的 URL (test.php?user=php
) 作为下一轮处理的输入重新开始。
- 请求被重写为
test.php?user=php
(再次)。
- 由于 URL 已通过,重写过程停止,请求最终被重写为
/test.php?user=php
。
解决方案 A - 使用 END
标志
一个解决方案是简单地使用 END
标志 (Apache 2.4) 而不是 L
来防止重写引擎“循环”。一旦指令被处理,它就会停止。例如:
RewriteRule (\w+)/?$ test.php?user= [END]
解决方案 B - 使正则表达式更具体
另一个解决方案(或同时)是使正则表达式更具体,使其不匹配 test.php
。 IE。仅匹配您期望的 URL 格式。
正则表达式 (\w+)/?$
似乎过于通用,因为它基本上只是匹配 URL 路径上的最后一组 letters/numbers。如果您只想匹配数字(“用户 ID”),那么您可以使正则表达式更具限制性,只匹配数字。
您还应该将正则表达式锚定在开头,以便它匹配整个路径段,而不是只捕获匹配的最后部分。事实上,简单地锚定上述正则表达式也可以解决这个问题,因为 test.php
将无法匹配,因为 \w
不匹配点。
例如:
RewriteRule ^(\d+)/?$ test.php?user= [L]
这将仅匹配最后一个路径段中的数字。
If I try with
RewriteRule ^prezzo/account/(\w+)/?$ prezzo/account/test.php?user= [L]
I get 404 not found although htaccess tester reports that the rule is
applied correctly and the URL is rewritten
如果 .htaccess
文件位于 /prezzo/account
子目录中(如您所述),则上述内容永远不会匹配,指令不执行任何操作。
该测试工具假定 .htaccess
文件仅位于文档根目录中。如果您的 .htaccess
位于文档根目录而不是子目录,那么该指令确实可以。
在目录上下文中(例如.htaccess
)RewriteRule
模式匹配URL-包含 .htaccess
文件的目录的相对路径 。
旁白:
在您的 link 中,整个文件似乎是:
RewriteEngine On
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{REQUEST_FILENAME} !-l
#RewriteRule . index.php [L]
RewriteRule (\w+)/?$ test.php?user= [L]
第一条规则已被注释掉,因此不适用于此处。但是,如果您取消注释第一条规则,那么规则的顺序是错误的。由于对 /prezzo/account/1
的请求将首先被重写为 index.php
并且您会遇到与以前相同的问题。
规则的顺序很重要。
我真的不明白我哪里做错了。我正在尝试将规则应用于
http://localhost/prezzo/account/1
所以改写为
http://localhost/prezzo/account/test.php?user=1
我将 UniformServer 用作 WAMP。我将 .htaccess
文件放在我正在处理的子文件夹中 (prezzo/account/),规则如下:
RewriteEngine On
RewriteRule (\w+)/?$ test.php?user= [L]
htaccess tester 报告规则已正确应用。
但是当我转到 URL 时 http://localhost/prezzo/account/1
和 test.php
被加载 - 其中仅包含
<?php
echo $_GET['user'];
?>
它returns字符串“php”而不是“1”.
如果我尝试
RewriteRule ^prezzo/account/(\w+)/?$ prezzo/account/test.php?user= [L]
我收到 404 not found 尽管 htaccess tester 报告规则应用正确并且 URL 被重写为
http://localhost/prezzo/account/test.php?user=1
如果我在地址栏中 copy/paste 就可以了。
But when I go to the URL
http://localhost/prezzo/account/1
andtest.php
is loaded [...] it returns the string "php" instead of "1".
是的,发布的规则符合预期。
这似乎在“htaccess 测试器”中有效,因为该工具只对文件进行单次传递,这不是真实服务器的工作方式。
RewriteRule (\w+)/?$ test.php?user= [L]
当您请求时 /prezzo/account/1
然后...
- 请求重写为
test.php?user=1
L
标志使重写引擎使用重写的 URL (test.php?user=1
) 作为下一轮处理的输入重新开始。- 请求被重写为
test.php?user=php
,因为正则表达式(\w+)/?$
捕获了test.php
的php
部分。 (\w
shorthand 字符 class 排除了点并且正则表达式没有锚定。) L
标志使重写引擎使用重写的 URL (test.php?user=php
) 作为下一轮处理的输入重新开始。- 请求被重写为
test.php?user=php
(再次)。 - 由于 URL 已通过,重写过程停止,请求最终被重写为
/test.php?user=php
。
解决方案 A - 使用 END
标志
一个解决方案是简单地使用 END
标志 (Apache 2.4) 而不是 L
来防止重写引擎“循环”。一旦指令被处理,它就会停止。例如:
RewriteRule (\w+)/?$ test.php?user= [END]
解决方案 B - 使正则表达式更具体
另一个解决方案(或同时)是使正则表达式更具体,使其不匹配 test.php
。 IE。仅匹配您期望的 URL 格式。
正则表达式 (\w+)/?$
似乎过于通用,因为它基本上只是匹配 URL 路径上的最后一组 letters/numbers。如果您只想匹配数字(“用户 ID”),那么您可以使正则表达式更具限制性,只匹配数字。
您还应该将正则表达式锚定在开头,以便它匹配整个路径段,而不是只捕获匹配的最后部分。事实上,简单地锚定上述正则表达式也可以解决这个问题,因为 test.php
将无法匹配,因为 \w
不匹配点。
例如:
RewriteRule ^(\d+)/?$ test.php?user= [L]
这将仅匹配最后一个路径段中的数字。
If I try with
RewriteRule ^prezzo/account/(\w+)/?$ prezzo/account/test.php?user= [L]
I get 404 not found although htaccess tester reports that the rule is applied correctly and the URL is rewritten
如果 .htaccess
文件位于 /prezzo/account
子目录中(如您所述),则上述内容永远不会匹配,指令不执行任何操作。
该测试工具假定 .htaccess
文件仅位于文档根目录中。如果您的 .htaccess
位于文档根目录而不是子目录,那么该指令确实可以。
在目录上下文中(例如.htaccess
)RewriteRule
模式匹配URL-包含 .htaccess
文件的目录的相对路径 。
旁白:
在您的 link 中,整个文件似乎是:
RewriteEngine On #RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_FILENAME} !-d #RewriteCond %{REQUEST_FILENAME} !-l #RewriteRule . index.php [L] RewriteRule (\w+)/?$ test.php?user= [L]
第一条规则已被注释掉,因此不适用于此处。但是,如果您取消注释第一条规则,那么规则的顺序是错误的。由于对 /prezzo/account/1
的请求将首先被重写为 index.php
并且您会遇到与以前相同的问题。
规则的顺序很重要。