嗨,我正在努力用.htaccess实现两件事,大概是每件事都有同样的问题。
我已成功将名为site-version
的Cookie设置为au
或us
。
如果设置了Cookie,我希望http://www.example.com和http://www.example.com/重定向(内部)到http://www.example.com/home-au.html(如果cookie site-version = au)。我还想设置一个环境变量SITE_VERSION = au。
RewriteCond %{HTTP_COOKIE} site-version=(au|us) [NC]
RewriteRule ^/?$ /home-%1.html [NC,QSA,E=SITE_VERSION:%1]
问题似乎是RewriteRule上的正则表达式。如果我将其设置为.*
,一旦它放弃循环,它似乎成功设置了环境变量,但仍然没有重写请求。
如果网址为http://www.example.com/a-specific-page.html或http://www.example.com/another-specific-page.html并且设置了Cookie,我想重定向到http://www.example.com/a-specific-page-au.html或http://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中我再次翻译这些网址,所以我不想要L标志,但我也尝试过:
RewriteRule ^(.*)\.html$ index.php?q=$1-au.html [QSA,E=SITE_VERSION:au,L]
我在这些主题上尝试过很多小变化,没有触发重写。
编辑:我发现我的理解存在根本差距。 URL rewrites trigger another loop通过.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]
答案 0 :(得分:1)
在我的评论中,我已经测试了没有RewriteCond的第一套规则,
RewriteRule ^/?$ /home-%1.html [NC,QSA,E=SITE_VERSION:%1]
我得到了这个:
http://www.example.com/ => http://www.example.com/home-.html
第二个规则集有一个可见错误:%{THE_REQUEST} ^(特定页面|另一个特定页面).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]
答案 1 :(得分:0)
完整的解决方案。这样做如下:
检测网址参数?site-version,如果找到,则在客户端设置一个名为site-version的cookie,存储国家代码(au,eu,za等),持续2年(1051200)分钟)。然后它会从URL中删除该参数,并让用户的浏览器再次请求原始URL。
除非,如果site-version = uk,这是网站的默认设置,那么cookie将被删除(请参阅co
标志中的-1)。
特定页面具有本地版本。可以通过将国家/地区代码添加到URL来访问它们。所以澳大利亚版本的costs.html是cost-au.html。
如果检测到cookie(可能是重复访问),或者可能是由于上面步骤1中的重定向,则会检查URL。如果URL是具有本地版本的页面之一,则会将国家/地区代码添加到URL。然后将URL传递给index.php - 这是获得令人愉悦的搜索引擎友好URL的常用方法。重写URL会触发.htaccess的另一次迭代。 (Nb。据我所知,E =这些规则上的标志没有达到任何效果,因为通过环境变量重复.htaccess时会丢失.E =如果URL被更改,则标志实际上无效,因为它们什么都不做。)
如果检测到cookie,则该值存储在名为HTTP_SITE_VERSION的环境变量中。 (环境变量应始终以HTTP_
为前缀,因为运行suexec的服务器会忽略不以HTTP_
开头的变量.supexec是一种Apache功能,允许脚本由用户以外的用户运行运行Apache进程,因此在共享主机中可能很常见。)
我的PHP提供更改后的URL,即costs-au.html,不知道它已被更改。 (仅供参考,浏览器网址为costs.html,因为这是内部重定向。)
对于所有页面,无论它们是否在列表中并具有翻译,都会设置环境变量。 PHP使用$ site_version = getenv('HTTP_SITE_VERSION')检测到这一点(对于UK,它返回false,因为cookie和变量未设置,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建议的两个更改:
将我想要匹配的字符串放入RewriteRule行而不是RewriteCond。对我的愚蠢监督。
请勿分两步更改网址,直接转到index.php?q = ..而不是通过新网址,并添加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_
为前缀。