htaccess 2 变量问题

htacces 2 variables issues

之前 我安装了 SSL,一切正常!!这是我的根网络服务器 .htaccess 文件中的代码:

Options +MultiViews
RewriteEngine On
RewriteCond %{HTTP_HOST} andrea\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://andrea.com/ [R,L]

RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule (.*) .php [L]

它能正常工作,而且它完全按照我的意愿行事。例如,如果我去:

www.andrea.com/account

它访问“www.andrea.com/account.php”。这就是我想要的。 但是,我确实在根目录中有一个名为“products”的文件夹。该文件夹中还有另一个“.htaccess”文件,我不知道必须更改这两个文件中的哪一个才能使下面的内容正常工作。

当您转到此 url 时: http:____/产品/查看/Hello/Goodbye

我想让它访问 'products' 文件夹和 php 文件中的“view.php”,我可以这样做:

$id = $_GET["id"];    //      This would have "Hello"
$cat = $_GET["cat"];    //   This would have "Goodbye"

当我在“产品”文件夹中使用此 htaccess 时,效果很好:

RewriteEngine on
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=&cat=

上面这段代码的问题是,如果我去: http:____/产品/Hello/Goodbye

我想让它访问“产品”文件夹中的“index.php”。但相反,它转到了“view.php”!!这就像上面的 htaccess 代码强制所有转到 view.php(只有当我在 url 中有“view/____”时才应该这样做。 我希望上面的 url 转到“产品”文件夹中的“index.php”,在该文件中我应该能够访问 ID 和 CAT 变量。

有什么想法可以更改我的 .htaccess 文件吗?抱歉,我花了 2 个多小时我看不懂代码底部的一行,但它不起作用:/

您可以使用以下规则将 /products/Hello/Goodbye 重写为 /products/index.php .

RewriteRule ^Hello/GoodBye/?$ /product/index.php?id=hello&cat=Goodbye  [L,NC]

这是您的完整 /product/.htaccess .

RewriteEngine on
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#rewrite /products/Hello/GoodBye to /products/index.php
RewriteRule ^Hello/GoodBye/?$ /products/index.php?id=Hello&cat=Goodbye  [L,NC]
###################
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=&cat=
 Options +MultiViews

首先,您应该禁用 多视图。在 to your 中,我关于使用 MultiViews 的建议在您的问题上下文中严格来说是一种“替代”方法。您不能同时使用这两种方法(mod_rewrite MultiViews)来处理无扩展名 URLs。并且由于您现在想要做更多的事情并传递参数,因此 MultiViews 只会产生冲突。 (多视图可能会“获胜”并且不会传递任何参数。)

此外,您是否特别需要 /products 子目录中的附加 .htaccess 文件?在文档根目录中有一个 .htaccess 文件(可以说)会更容易。这将避免必须重复 HTTP 到 HTTPS 重定向(尽管您实际上没有在子目录 .htaccess 文件中包含 HTTP 到 HTTPS 重定向?)。

# /products/.htaccess
RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=&cat=

此指令匹配 view/Hello/Goodbye Hello/Goodbye,这解释了为什么所有内容都被写入您的 view.php 脚本。但是,它实际上也没有按照您所说的去做——这令人费解。如果您请求 /products/view/Hello/Goodbye 那么它会将请求重写为 /products/view.php?id=view&cat=Hello/Goodbye - 这不是本意(除非启用了 MutliViews,在这种情况下根本不会传递任何参数)。

在尝试重写为 views.php 之前,您需要实际检查请求的 URL 路径中的 views。如果 views 不存在,则改写为 index.php。这种“条件分支”可以通过简单地按照“更具体”规则优先的顺序排列指令来实现。

例如,在您的根 .htaccess 文件中尝试以下操作。 (并完全删除 /products/.htaccess 文件。)

# Ensure that MultiViews is disabled
Options -MultiViews

RewriteEngine On

# HTTP to HTTPS canonical redirect
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://example.com/ [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]

# 1. Rewrite "/products/view/<id>/<cat>" to "/products/view.php?id=<id>&cat=<cat>
RewriteRule ^(products/view)/([^/]*)/?(.*) .php?id=&cat= [L]

# 2. Rewrite "/products/<id>/<cat>" to "/products/index.php?id=<id>&cat=<cat>
RewriteRule ^(products)/([^/]*)/?(.*) /index.php?id=&cat= [L]

# 3. Extensionless URLs for other requests
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule (.*) .php [L]

以上 3 条规则的顺序很重要。最具体的规则是第一个。包括 L 标志以防止进一步(不必要的)处理。

请注意,根据您的原始指令,对于 /products/view/Hello/Goodbye(或 /products/Hello/Goodbye)形式的请求,Hello/Goodbye 部分完全是可选的,自然会导致idcat URL 参数正在设置,但为空。

此外,根据您的原始指令,/products/view/Hello/Goodbye/foo/bar/baz 形式的请求将导致 cat URL 参数设置为 Goodbye/foo/bar/baz(后面的任何内容初始路径段)。

如果您使正则表达式更具体并且只匹配您需要的内容,则您不一定需要检查请求是否映射到文件或目录(相对 昂贵)匹配。例如,您的正则表达式 /([^/]*)/?(.*) 目前几乎可以匹配 任何东西 。但是,如果您的 <id><cat> 变量只能由小写字母组成(例如),那么这可以避免文件系统检查的需要。

其他说明:

  • 您需要检查 HTTP 到 HTTPS 重定向中的主机名吗?您托管多个域吗?否则不需要检查 HTTP_HOST 服务器变量的条件。