1

嗨,我正在努力用 .htaccess 实现两件事,大概每个问题都相同。

我成功设置了一个名为orsite-version的cookie 。auus

如果设置了 cookie,我希望http://www.example.comhttp://www.example.com/重定向(内部)到http://www.example.com/home-au.html(如果 cookie 站点版本=au)。我还想设置一个环境变量 SITE_VERSION=au。

RewriteCond %{HTTP_COOKIE} site-version=(au|us) [NC]
RewriteRule ^/?$ /home-%1.html [NC,QSA,E=SITE_VERSION:%1]

问题似乎是 RewriteRule 上的正则表达式。如果我将其设置为.*,一旦它放弃循环,它似乎会成功设置环境变量,尽管仍然没有重写请求。

如果 URL 是http://www.example.com/a-specific-page.htmlhttp://www.example.com/another-specific-page.html并且设置了 cookie,我想重定向到http://www.example.com/a-specific-page-au.htmlhttp://www.example.com/another-specific-page-au.html,即附加-au到文件名。(并设置环境变量。)

RewriteCond %{THE_REQUEST} ^(a-specific-page|another-specific-page)\.html$ [NC]
RewriteCond %{HTTP_COOKIE} site-version=au [NC]
RewriteRule ^(.*)\.html$ /$1-au.html [QSA,E=SITE_VERSION:au]

后来在 htaccess 中,我再次翻译了这些 URL,所以我不想要 L 标志,但是我也尝试过:

RewriteRule ^(.*)\.html$ index.php?q=$1-au.html [QSA,E=SITE_VERSION:au,L]

我在这些主题上尝试了许多细微的变化,没有一个会触发重写。

编辑:我发现我的理解存在根本差距。URL 重写通过 .htaccess 触发另一个循环,因此我需要呈现整个文件而不是片段,这解释了为什么该解决方案有效但我仍然没有获得环境变量。

RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]


########## Set the cookie if the user selects a new country #############
#  The webpage submits the existing URL plus the site-version URL parameter.   #
#  The below strips the parameter and returns to the same URL with a cookie site-version. #
#  Unless the site-version is uk (default) in which case the cookie is deleted. #

RewriteCond %{QUERY_STRING} ^.*site-version=(au|us|za|eu)$
RewriteRule (.*) $1? [co=site-version:%1:example.com:1051200:/,R,E=SITE_VERSION:%1,L]

RewriteCond %{QUERY_STRING} ^.*site-version=uk$
RewriteRule (.*) $1? [co=site-version:uk:example.com:-1:/,R,E=SITE_VERSION:uk,L]

#####################
# If the cookie is present and the URL is either a-page.html or another-page.html append -au eg, a-page-au.html #

RewriteCond %{HTTP_COOKIE} site-version=au [NC]
RewriteRule ^(a-page|another-page)\.html$ index.php?q=$1-au.html [NC,QSA,E=SITE_VERSION:au,L]

##########################
# Normal Friendly URLs rewrite, ie, cookie not detected or it isn't one of the listed URLs #

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
4

2 回答 2

1

在我的评论中,我测试了第一个没有 RewriteCond 的规则集,

RewriteRule ^/?$ /home-%1.html [NC,QSA,E=SITE_VERSION:%1]

我得到了这个:

http://www.example.com/ =>     http://www.example.com/home-.html

第二个规则集有一个可见的错误:%{THE_REQUEST} ^(a-specific-page|another-specific-page).html$ [NC] 您可以尝试使用 %{REQUEST_URI} 而不是 %{THE_REQUEST}。%{THE_REQUEST} 涉及 GET 或 POST 等词。

所以你可以试试这个:

RewriteCond %{HTTP_COOKIE} site-version=(au|us) [NC]
RewriteRule ^/?$ /home-%1.html [NC,QSA,E=SITE_VERSION:%1]

RewriteCond %{HTTP_COOKIE} site-version=au [NC]
RewriteRule  ^(a-specific-page|another-specific-page)\.html$ /$1-au.html [NC,QSA,E=SITE_VERSION:au]

或者通过添加 R 标志来设置可见重定向,如下所示:

RewriteCond %{HTTP_COOKIE} site-version=(au|us) [NC]
RewriteRule ^/?$ /home-%1.html [R,QSA,E=SITE_VERSION:%1]

RewriteCond %{HTTP_COOKIE} site-version=au [NC]
RewriteRule  ^(a-specific-page|another-specific-page)\.html$ /$1-au.html [R,NC,QSA,E=SITE_VERSION:au]
于 2013-11-09T22:43:21.073 回答
0

完整的解决方案。这将执行以下操作:

  1. 检测 URL 参数 ?site-version,如果找到,在客户端设置一个名为 site-version 的 cookie,存储国家代码(au、eu、za 等),持续 2 年(1051200 分钟)。然后它从 URL 中删除参数并让用户的浏览器再次请求原始 URL。

  2. 除非,如果 site-version=uk,这是网站的默认设置,所以 cookie 被删除(参见co标志中的 -1)。

特定页面有它们的本地版本。通过将国家代码添加到 URL 来访问它们。所以澳大利亚版的costs.html是costs-au.html。

  1. 如果检测到 cookie(可能是重复访问,或者可能是由于上述步骤 1 中的重定向),则会检查 URL。如果 URL 是具有本地版本的页面之一,则将国家代码添加到 URL。然后将 URL 传递给 index.php - 获得美观、搜索引擎友好的 URL 的常用方法。URL 的重写通过 .htaccess 触发另一个迭代。(注意。据我所知,这些规则上的 E= 标志没有任何作用,因为当通过环境变量重复 .htaccess 时丢失了。如果 URL 发生更改,E= 标志实际上是无效的,因为它们一事无成。)

  2. 如果检测到 cookie,则该值将存储在名为 HTTP_SITE_VERSION 的环境变量中。(环境变量应始终以 为前缀HTTP_,因为运行 suexec 的服务器会忽略不以HTTP_.共享主机。)

  3. 我的 PHP 服务于更改后的 URL,即 cost-au.html,但不知道它已被更改。(仅供参考,浏览器 URL 是 cost.html,因为这是一个内部重定向。)

  4. 对于所有页面,无论它们是否在列表中并有翻译,都会设置环境变量。PHP 使用 $site_version = getenv('HTTP_SITE_VERSION') 检测到这一点(由于未设置 cookie 和变量,因此对于 UK 返回 false,而对于缺少的 var,getenv 返回 false)并显示适当的块,例如电话号码或地址。

因此,最终的可行解决方案是这样的(修复细节如下):

RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

########## Set the cookie if the user selects a new country #############
#  The webpage submits the existing URL plus the site-version URL parameter.   #
#  The below strips the parameter and returns to the same URL with a cookie site-version. #
#  Unless the site-version is uk (default) in which case the cookie is deleted. #

RewriteCond %{QUERY_STRING} ^.*site-version=(au|us|za|eu)$
RewriteRule (.*) $1? [co=site-version:%1:example.com:1051200:/,R,E=HTTP_SITE_VERSION:%1,L]

RewriteCond %{QUERY_STRING} ^.*site-version=uk$
RewriteRule (.*) $1? [co=site-version:uk:example.com:-1:/,R,E=HTTP_SITE_VERSION:uk,L]

#############################
# Once the URLs have been rewritten, htaccess is iterated through again - re-iterating loses the environment variable to re-set it here

RewriteCond %{HTTP_COOKIE} site-version=(au|us|eu|za|uk) [NC]
RewriteRule .* - [NC,E=HTTP_SITE_VERSION:%1]

#####################
# If the cookie is present and the URL is either a-page.html or another-page.html append -au eg, a-page-au.html #

RewriteCond %{HTTP_COOKIE} site-version=au [NC]
RewriteRule ^(a-page|another-page)\.html$ index.php?q=$1-au.html [NC,QSA,E=HTTP_SITE_VERSION:au,L]


##########################
# Normal Friendly URLs rewrite, ie, cookie not detected or it isn't one of the listed URLs #

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

我需要的修复:jacouh 建议的两个更改:

  1. 将我要匹配的字符串放入 RewriteRule 行而不是 RewriteCond。我的愚蠢疏忽。

  2. 不要分两步更改 URL,直接转到 index.php?q=.. 而不是通过新 URL,然后添加L标志。如果 URL 被任何规则更改,则重新迭代整个 htaccess。一步完成所有事情会使事情变得简单得多。

但这是不完整的。重写 URL 时,触发了通过 .htaccess 的新迭代。这将删除所有环境变量和带有 REDIRECT_ 前缀的标头。

所以我还需要在 .htaccess 的迭代中添加环境变量的设置,而不会触发重写。(当再次迭代 htaccess 文件时,如果有任何规则更改 URL,就会发生这种情况,环境变量会消失。很抱歉,这很冗长,但这很令人困惑。)所以我需要一个 htaccess 的迭代,它不会更改要在其中的 URL设置环境变量。因此需要添加

RewriteCond %{HTTP_COOKIE} site-version=(au|us|eu|za|uk) [NC]
RewriteRule .* - [NC,E=HTTP_SITE_VERSION:%1]

这会在 URL 被重写后在迭代中设置环境变量。嘿 presto,在我的服务器上工作。

但是当我推出它时,即使发生了重写,变量又消失了。

事实证明,在运行 suexec 以保护 PHP 的服务器上,环境变量需要以HTTP_.

于 2013-11-12T17:15:55.313 回答