.htaccess 如果第二个存在则删除第一个 php url 参数

.htaccess 如果第二个存在则删除第一个 php url 参数

这是我的.htaccess 代码:

RewriteCond %{REQUEST_URI} !^/pages/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)(/([^/]+))? pages.php?PAGE=$1&LINK=$3 [L]

*其中 $1 = 个人资料,$3 = john-smith

这是很好的重写方式https://example.com/profile/john-smith但我需要第二条重写规则https://example.com/john-smith仅当包含 john-smith 的第二个参数存在时。

谢谢你!

更新:(我的 .htaccess 文件的完整规则)

# protect files beginning with .
RewriteRule /\.(.*) - [NC,F]

# redirect HTTPS
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

# No root access without index.* and other security
RewriteEngine On
Options All -Indexes
RewriteBase /
DirectoryIndex index.php index.html index.htm
ErrorDocument 404 https://example.com/pages.php?PAGE=404

# Prevent upload malicious PHP files
<FilesMatch “\.(php|php\.)$”> 
Order Allow,Deny 
Deny from all 
</FilesMatch>

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

RewriteCond %{REQUEST_URI} !^/pages/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)(/([^/]+))? pages.php?PAGE=$1&LINK=$3 [QSA, L]

答案1

RewriteRule ^([^/]+)(/([^/]+))? pages.php?PAGE=$1&LINK=$3 [L]

这样做的“问题”在于它还会匹配 的请求/john-smith(第二组是可选的),但会将请求重写为pages.php?PAGE=john-smith&LINK=,而不是按pages.php?LINK=john-smith要求重写。为此,您需要一条单独的规则。它还会匹配/profile/john-smith/anything,丢弃/anything但仍会重写请求(多对一关系),这可能会让您的网站受到垃圾邮件发送者的攻击。

假设您不允许.在 URL 路径段中使用点 ( )(按照您的示例),那么就无需检查请求是否映射到文件。例如,/profile/john-smith如果您的所有文件都有文件扩展名,则请求永远无法映射到文件,因此文件系统检查是多余的。

请尝试以下操作:

# Rewrite exactly one path segment
# eg. /john-smith to pages.php?LINK=john-smith
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)$ pages.php?LINK=$1 [L]

# Rewrite exactly two path segments
# eg. /profile/john-smith to pages.php?PAGE=profile&LINK=john-smith
RewriteCond %{REQUEST_URI} !^/pages/ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)/([^/.]+)$ pages.php?PAGE=$1&LINK=$2 [L]

NC前述指令上的标志可能RewriteCond是多余的。

([^/.]+)- 我已将捕获子模式更改为排除点。第二条规则恰好匹配两个路径段,而不是一个或者两个路径段,如您的示例所示。

相关内容