【问题标题】:htacces 2 variables issueshtaccess 2变量问题
【发布时间】:2021-03-08 23:17:57
【问题描述】:

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

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

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

它可以正常工作,并且完全符合我的要求。所以如果我去例如:

www.andrea.com/account

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

当您访问此网址时: http:____/products/view/Hello/Goodbye

我希望它访问“产品”文件夹中的“view.php”,并且在那个 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=$1&cat=$2

上面这段代码的问题是,如果我去: http:____/products/你好/再见

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

对在我的 .htaccess 文件中进行哪些更改有任何想法吗?抱歉,我花了 2 个多小时,我的代码底部的一行我都看不懂,但它不起作用:/

【问题讨论】:

  • 您是否托管多个域? /products/.htaccess 文件中第一个重定向背后的意图是什么 - 这似乎与根目录中的 HTTP 到 HTTPS 重定向冲突?在 URL /view/Hello/Goodbye 中 - 哪些部分是可选的?您的指令暗示 HelloGoodbye 都可以是可选的 - 但这在您的问题中没有说明?

标签: .htaccess ssl ssl-certificate


【解决方案1】:

您可以使用以下规则将/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=$1&cat=$2

【讨论】:

  • 阿米特非常感谢您的回复!!!! :) 然而,“你好”和再见是需要释放而不是设置的变量。换句话说,网址应该能够包含任何内容。你知道我的意思吗?我应该可以去 /products/4729/gold 或者:/products/view/silver 我应该可以通过以下方式检索它: $id = $_GET["id"]; $cat = $_GET["cat"];您能否为我提供完整的 htaccess eirg 调整?我不能感谢你。
【解决方案2】:
 Options +MultiViews

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

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

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

该指令同时匹配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/$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]

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

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

# 3. Extensionless URLs for other requests
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.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(初始路径段之后的任何内容)。

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

其他说明:

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

【讨论】:

  • MrWhite 首先感谢您的精彩消息。我真的很感激你付出的所有时间。我完全按照你的要求做了,除了一件事,一切都很好。无论我使用“/products/view/200019/hejsan”还是“/products/view/200019”,当我尝试在 view.php 中进行 _GET 时,变量 ID 和 CAT 都是空的 :(
  • 我已经在我的开发服务器上对此进行了测试,它按预期工作(vars idcat 都填充正常 - 分别为该特定 URL 使用“200019”和“hejsan”) .澄清一下,代码是 完全 如上发布的?没有其他指令? MultiViews 是否被禁用并带有-(不是+)前缀?并且除了站点文档根目录中的.htaccess 文件之外,您没有其他.htaccess 文件?
  • 旁白:我对答案中的代码做了一个非常小的改动——我删除了RewriteRule上的斜杠前缀susbtitution i> 字符串(两条规则)。但是,我不希望这会产生任何明显的差异 - 更多的是代码整洁/优化。
  • "在我安装 SSL 之前,一切运行良好!!" - 只是补充一点,这些问题不应该与“安装 SSL”有任何关系。除非 SSL vHost 具有其他/不同的指令或 .htaccess 覆盖未启用?但在那种情况下,我会期待不同的回应。您有权访问服务器配置吗?
  • 另外,请确保您已清除浏览器缓存并且没有看到缓存响应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
  • 2012-12-08
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
相关资源
最近更新 更多