.htaccess 使用两个包含空格的参数重写URL会导致403 Forbidden

knpiaxh1  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(121)

我有一个PHP文件:

example.com/products/index.php

我的目标是能够做到这一点:

example.com/products/186/Hello to you

在PHP中,我可以做$_GET['id'],它将是186
$_GET['cat']表示“你好”。

到目前为止,我在下面尝试了这个,但我得到:

您没有权限访问该页面!此外,尝试使用ErrorDocument时遇到403 Forbidden错误

Options -MultiViews

RewriteEngine On

# HTTP to HTTPS canonical redirect
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://example.com/$1 [R=301,L]

# Abort early if the request already maps to (or looks like) a file or directory
RewriteCond %{REQUEST_URI} \.\w{2,4}$ [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

RewriteRule ^(products)/([^/]*)/?(.*) $1/index.php?id=$2&cat=$3 [L]

# 3. Extensionless URLs for other requests  (this below works fine and is for something else)
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]
jm81lzqq

jm81lzqq1#

您的“403 Forbidden”问题与Apache最近的更新以及您请求的URL中的 * 空格 * 有关。如以下问题所述:

RewriteRule ^(products)/([^/]*)/?(.*) $1/index.php?id=$2&cat=$3 [L]

由于您在请求的URL中允许 * 空格 *(在请求中编码为%20),您正在 * 捕获 * 并传递给 * 替换 * 字符串,因此需要包含B标志以便对反向引用进行URL编码。
请尝试以下操作:

RewriteRule ^(products)/([^/]*)/?(.*) $1/index.php?id=$2&cat=$3 [B,L]

然而,你的正则表达式(RewriteRulepattern /第一个参数)看起来太“灵活”了,因为它使第三个路径段是可选的(即:格式为/products/anything的URL将被接受)-这是故意的吗?
要只匹配/products/<id>/<cat>的URL(其中<id>仅由数字0-9组成),则应将RewriteRulepattern 修改为如下内容:

^(products)/(\d+)/(.+)

在关于使用$_SERVER['REQUEST_URI']而不是传递URL参数的注解中提到了这一点。这是可以的,但在这种情况下并没有保存太多(如果有的话),因为这看起来像是一个孤立的案例,而不是如何构建您的网站的其余部分。在这种情况下,.htaccess中的规则将变为:

RewriteRule ^(products)/\d+/. $1/index.php [L]

(* 旁白:* 尽管这种方法的一个额外好处是它自然地防止了通过index.php?id=<id>&cat=<cat>形式的URL访问相同的资源,从而避免了潜在的 * 重复内容 * 问题。在.htaccess中可以使用一个额外的规则将此类请求重定向到规范URL。
在PHP中,您直接从请求的URL路径(存储在$_SERVER['REQUEST_URI']超全局中)解析值。例如:

<?php
$urlPath = parse_url($_SERVER['REQUEST_URI'],PHP_URL_PATH);
$urlPathParts = explode('/',$urlPath);
$id ??= $urlPathParts[1];
$cat ??= $urlPathParts[2];

相关问题