當用戶代理匹配 Twitter 或 Facebook 時,我想將 url 重定向到我的 ogp 頁面。
我的重定向影像是這樣的。
/news/detail.html?id=1 -> /api/v1/informations/ogp/1?lang=ja
/news/detail.html?id=1&lang=en -> /api/v1/informations/ogp/1?lang=en
/sport/detail.html?id=1 -> /api/v1/sports/ogp/1?lang=ja
/sport/detail.html?id=1&lang=en -> /api/v1/sports/ogp/1?lang=en
/event/common/detail.html?id=1 -> /api/v1/events/ogp/1?lang=ja
/event/common/detail.html?id=1 -> /api/v1/events/ogp/1?lang=ja
/event/special/detail.html?id=2&lang=en -> /api/v1/events/ogp/2?lang=en
/event/special/detail.html?id=2 -> /api/v1/events/ogp/2?lang=ja
所以我寫了 htaccess,Env 引數作業正常,但是當 RewriteRule 接管兩個或更多時,重寫規則不起作用。
<IfModule mod_setenvif.c>
SetEnvIfNoCase User-Agent "^facebookexternalhit.*$" UA_FACEBOOK=1
SetEnvIfNoCase User-Agent "^facebookplatform.*$" UA_FACEBOOK=1
SetEnvIfNoCase User-Agent "^Twitterbot.*$" UA_TWITTER=1
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )&lang=(\w )($|&)
RewriteRule ^news/detail.html$ /api/v1/informations/ogp/%2?lang=%3 [R,L]
RewriteRule ^sport/detail.html$ /api/v1/sports/ogp/%2?lang=%3 [R,L]
RewriteRule ^event/common/detail.html$ /api/v1/events/ogp/%2?lang=%3 [R,L]
RewriteRule ^event/special/detail.html$ /api/v1/events/ogp/%2?lang=%3 [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )($|&)
RewriteRule ^news/detail.html$ /api/v1/informations/ogp/%2?lang=ja [R,L]
RewriteRule ^sport/detail.html$ /api/v1/sports/ogp/%2?lang=ja [R,L]
RewriteRule ^event/common/detail.html$ /api/v1/events/ogp/%2?lang=ja [R,L]
RewriteRule ^event/special/detail.html$ /api/v1/events/ogp/%2?lang=ja [R,L]
</IfModule>
我想用相同的 RewriteCond 重定向它們,怎么做?
即使是臟代碼也是受歡迎的!
uj5u.com熱心網友回復:
/news/detail.html?id=1 -> /api/v1/informations/ogp/1?lang=ja /news/detail.html?id=1&lang=en -> /api/v1/informations/ogp/1?lang=en /sport/detail.html?id=1 -> /api/v1/sports/ogp/1?lang=ja /sport/detail.html?id=1&lang=en -> /api/v1/sports/ogp/1?lang=en /event/common/detail.html?id=1 -> /api/v1/events/ogp/1?lang=ja /event/common/detail.html?id=1&lang=en -> /api/v1/events/ogp/1?lang=en /event/special/detail.html?id=2 -> /api/v1/events/ogp/2?lang=ja /event/special/detail.html?id=2&lang=en -> /api/v1/events/ogp/2?lang=en
這實際上只有 4 個 URL 映射(當lang引數被省略時,它分配了一個默認值 - 目標保持不變),所以您只需要 4 個規則(如果您提取lang引數)。最后 2 個重定向到同一個目標,因此可以輕松組合(使用正則運算式交替(common|special)),只剩下 3 個需要的單獨規則。
您可以這樣做以避免任何重復:
RewriteEngine On
RewriteBase /api/v1
# Get "lang" (default to "ja")
RewriteRule ^ - [E=LANG:ja]
RewriteCond %{QUERY_STRING} (?:^|&)lang=(\w )($|&)
RewriteRule ^ - [E=LANG:%1]
# Get "id" (if any)
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d )($|&)
RewriteRule ^ - [E=ID:%1]
# If not Facebook|Twitter OR no ID then skip the next 3 rules
RewriteCond %{HTTP_USER_AGENT} !^(facebook(externalhit|platform)|twitterbot) [NC,OR]
RewriteCond %{ENV:ID} ^$
RewriteRule ^ - [S=3]
# If here then Facebook|Twitter and "id" param are passed, LANG already set
RewriteRule ^news/detail\.html$ informations/ogp/%{ENV:ID}?lang=%{ENV:LANG} [R,L]
RewriteRule ^sport/detail\.html$ sports/ogp/%{ENV:ID}?lang=%{ENV:LANG} [R,L]
RewriteRule ^event/(common|special)/detail\.html$ events/ogp/%{ENV:ID}?lang=%{ENV:LANG} [R,L]
這里的技巧是當用戶代理不是Facebook 或 Twitter(或不存在URL 引數)時,使用S( skip) 標志跳過以下 3 條規則- 顛倒邏輯。這意味著只有當用戶代理是Facebook 或 Twitter 并且URL 引數存在時,才會處理最后 3 條規則。idid
請注意,我使用了非捕獲子模式來確保反向參考(即 . %1)僅參考我們感興趣的組。
注意:我將RewriteBase最后 3 條規則更改為“簡化”。盡管如果您有其他指令,那么您可能希望將其更改回來。
我嘗試了使用 If 指令的方法,但它不起作用
您當前的規則將無法匹配<If>指令(Apache 2.4),因為在這種情況下,RewriteRule指令匹配絕對檔案路徑,而不是相對 URL 路徑(可能是因為<If>容器合并得很晚)。
如果沒有沖突,這里一個簡單的解決方法是從模式^的開頭洗掉字串開頭的錨點 ( ),以便能夠匹配表單的檔案路徑。(雖然我可能會添加一個斜杠前綴以避免任何部分路徑段匹配。)RewriteRule /absolute/file/path/to/public_html/news/detail.php
所以,你可能會這樣寫,而不是使用<If>運算式:
RewriteEngine On
# Get "id" (if any)
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d )($|&)
RewriteRule ^ - [E=ID:%1]
# Facebook|Twitter AND "id" param are passed
<If "%{HTTP_USER_AGENT} =~ /^(?i)(facebook(externalhit|platform)|twitterbot)/ && reqenv('ID') =~ /\d /">
# Get "lang" (default to "ja")
RewriteRule ^ - [E=LANG:ja]
RewriteCond %{QUERY_STRING} (?:^|&)lang=(\w )($|&)
RewriteRule ^ - [E=LANG:%1]
# Redirects
RewriteRule /news/detail\.html$ /api/v1/informations/ogp/%{ENV:ID}?lang=%{ENV:LANG} [R,L]
RewriteRule /sport/detail\.html$ /api/v1/sports/ogp/%{ENV:ID}?lang=%{ENV:LANG} [R,L]
RewriteRule /event/(common|special)/detail\.html$ /api/v1/events/ogp/%{ENV:ID}?lang=%{ENV:LANG} [R,L]
</If>
uj5u.com熱心網友回復:
這個骯臟的代碼做了我想做的事。
<IfModule mod_setenvif.c>
SetEnvIfNoCase User-Agent "^facebookexternalhit.*$" UA_FACEBOOK=1
SetEnvIfNoCase User-Agent "^facebookplatform.*$" UA_FACEBOOK=1
SetEnvIfNoCase User-Agent "^Twitterbot.*$" UA_TWITTER=1
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )&lang=(\w )($|&)
RewriteRule ^news/detail.html$ /api/v1/informations/ogp/%2?lang=%3 [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )&lang=(\w )($|&)
RewriteRule ^sport/detail.html$ /api/v1/sports/ogp/%2?lang=%3 [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )&lang=(\w )($|&)
RewriteRule ^event/common/detail.html$ /api/v1/events/ogp/%2?lang=%3 [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )&lang=(\w )($|&)
RewriteRule ^event/special/detail.html$ /api/v1/events/ogp/%2?lang=%3 [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )($|&)
RewriteRule ^news/detail.html$ /api/v1/informations/ogp/%2?lang=ja [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )($|&)
RewriteRule ^sport/detail.html$ /api/v1/sports/ogp/%2?lang=ja [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )($|&)
RewriteRule ^event/common/detail.html$ /api/v1/events/ogp/%2?lang=ja [R,L]
RewriteCond %{ENV:UA_FACEBOOK} ^1$ [OR]
RewriteCond %{ENV:UA_TWITTER} ^1$
RewriteCond %{QUERY_STRING} (^|&)id=(\d )($|&)
RewriteRule ^event/special/detail.html$ /api/v1/events/ogp/%2?lang=ja [R,L]
</IfModule>
我嘗試了使用 If 指令的方法,但它不適用于我的環境變數,如下面的代碼
<If "%{ENV:UA_FACEBOOK} -eq 1 || %{ENV:UA_TWITTER} -eq 1"></If>
所以我通過一次又一次地撰寫大量相同的 RewriteCond 來解決這個問題。
如果你有更好的方法來寫這個,我歡迎它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/435975.html
上一篇:更改域時未正確重定向https
