[英]Internal htaccess redirects based on combination of request and cookie not firing
嗨,我正在努力用.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上的正則表達式。 如果將其設置為.*
,一旦它放棄循環,它似乎已成功設置了環境變量,盡管仍然沒有重寫請求。
如果該URL是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中,我再次翻譯了這些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]
如我的評論所述,我已經測試了沒有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]
完整的解決方案。 這將執行以下操作:
檢測URL參數?site-version,如果找到,則在客戶端上設置一個cookie,稱為site-version,並存儲國家/地區代碼(au,eu,za等),持續2年(1051200分鍾)。 然后,它將參數從URL中刪除,並使用戶的瀏覽器再次請求原始URL。
除非是site-version = uk,否則這是網站的默認設置,因此將刪除cookie(請參閱co
標志中的-1)。
特定頁面有本地版本。 通過將國家/地區代碼添加到URL來訪問它們。 因此,澳大利亞版的costs.html是costs-au.html。
如果檢測到cookie(可能是重復訪問),或者可能是由於上述步驟1中的重定向所致,則將檢查URL。 如果URL是具有本地版本的頁面之一,則將國家/地區代碼添加到URL。 然后將該URL傳遞給index.php-具有令人愉悅且對搜索引擎友好的URL的常用方法。 URL的重寫通過.htaccess觸發了另一個迭代。 (Nb。據我所知,這些規則中的E =標志無法實現任何事情,因為通過環境變量重申.htaccess時丟失了。如果URL更改,E =標志實際上是無效的,因為它們一無所獲。)
如果檢測到cookie,則該值將存儲在名為HTTP_SITE_VERSION的環境變量中。 (環境變量應始終以HTTP_
為前綴,因為運行suexec的服務器會忽略不以HTTP_
開頭的變量。suexec是Apache的一項功能,它允許腳本由運行Apache進程的用戶以外的其他用戶運行。在共享主機之間通用)。
我的PHP提供更改后的URL,即costs-au.html,卻未意識到它已被更改。 (僅供參考,瀏覽器URL為cost.html,因為這是內部重定向。)
對於所有頁面,無論它們是否在列表中並且具有翻譯,都將設置環境變量。 PHP使用$ site_version = getenv('HTTP_SITE_VERSION')(在英國,因為未設置cookie和變量而返回false,而對於缺少的vars,則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。 我的傻傻的監督。
不要分兩步更改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后,這將在迭代中設置環境變量。 嘿,我在服務器上工作過。
但是當我推出它時,即使發生了重寫,變量也再次消失了。
事實證明,在運行suexec以保護PHP的服務器上,環境變量需要以HTTP_
為前綴。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.