.htaccess 重写规则问题
P粉316890884
P粉316890884 2024-03-20 00:01:01
[PHP讨论组]

.htaccess 重写规则存在问题。将用户电子邮件中的 URL 传递到浏览器,其中包含用于密码重置的令牌。

当前 .htaccess 规则:

Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.DOMAIN\.com [NC]
RewriteRule ^(.*)$ https://DOMIAN.com/$1 [L,R=301]

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

RewriteCond %{THE_REQUEST} ^(?:GET|POST)\ /.*\.php\ HTTP.*$ [NC]
RewriteRule ^(.*)\.php$ $1 [R=301,L]

当用户尝试去

example.com/activate/00803e6632236414ebcdc34c7e7690d764e567083fac6

在调试中产生这些错误

example.com/activate/00803e6632236414ebcdc34c7e7690d764e567083fac6.php.php.php.php.php.php.php.php.php.php

所以我按照下面的注释更新 .htaccess,如下所示:

Options +FollowSymLinks -MultiViews

RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.EXAMPLE\.com [NC]
RewriteRule ^(.*)$ https://EXAMPLE.com/$1 [L,R=301]

RewriteCond %{THE_REQUEST} ^(?:GET|POST)\ /.*\.php\ HTTP.*$ [NC]
RewriteRule ^(.*)\.php$ $1 [R=301,L]

# Rewrite extensionless ".php" URLs
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.+) $1.php [L]

# Rewrite "/<file>/<code>" to "/<file>.php/<code>"
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/]+)/([a-f0-9])$ $1.php/$2 [L]

我收到以下错误:

AH00128:文件不存在:/var/www/html/htdocs/activate/00803e6632236414ebcdc34c7e7690d764e567083fac6

P粉316890884
P粉316890884

全部回复(1)
P粉651109397

此规则的问题在于您正在检查一个文件系统路径(即 %{REQUEST_FILENAME}\.php)并重写到另一个文件系统路径($1.php)。这些不一定指同一件事。对于对 /activate/foo 的请求,其中 activate 不是文件系统目录,则 REQUEST_FILENAME 的格式为 /var/www/html/htdocs/activate (因此文件检查成功,因为 /var/www/html/ htdocs/activate.php 存在),但它将请求重写为 activate/foo.php (使用 $1 反向引用) - 该请求不存在。它将重复执行此操作,每次附加 .php (直到达到内部重写限制;默认 10)。

Aside#1: 在检查 request+.php 是否映射到文件之前,无需检查请求是否映射到目录且未映射到文件。当只需要一项时,这是 3 次(昂贵的)文件系统检查。

Aside#2: 您也不需要反斜杠转义 TestString (第一个参数)中的文字点,因为这是一个“普通”字符串,不是正则表达式。

此规则需要更正,以便您测试最终要重写的相同文件路径。例如:

# Rewrite extensionless ".php" URLs
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.+) $1.php [L]

然后,您需要一条附加规则将请求 /activate/ 重写为 /activate.php/ (将 / 作为路径信息传递给您的脚本)。如果这是一次性的,这可能是“硬编码”的。例如:

# Rewrite "/activate/" to "/activate.php/"
RewriteRule ^(activate)/([a-f0-9]+)$ $1.php/$2 [L]

(我假设 是一个十六进制序列,在您的示例中似乎就是这种情况。)

或者,如果您有类似的请求,请使其更通用。例如。 /<文件>//<文件>.php/。例如:

# Rewrite "//" to "/.php/"
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/]+)/([a-f0-9]+)$ $1.php/$2 [L]

旁白:

此规则(外部重定向)应上述重写之前。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号