前言與需求
自動電商平臺歸屬了大數據研究院之後,我又恢復了那個“把nginx當成爸爸”的日子。開發不斷地提出了的要求,我一樣一樣的疲命應付,並且在應付後記錄下來,就怕以後再遇到類似的問題。
這次的需求是一個跳轉,滿足某個條件之後把“http://dvlshop.lechange.com/index.php/wap/?client_id=lc_mall_m&redirect_uri=https%3A%2F%2Fdvlshop.lechange.com%2Fopenapi%2Ftrustlogin_api%2Fparse%2Fwap_trustlogin_lecheng%2Fcallback&response_type=code&scope=read&state=http%3A%2F%2Fdvlshop.lechange.com%2Findex.php%2Fwap&user=token%2Flcid_9f9lmo2u6i7hkl6t6eaodn2blmg5jbsg&expire=1514191636&source_type=lc_app&nonce=cdizHO6uvSx5JK79Kmtz5RBpSi0ROhpF&signature=VeCceYCWDE6BZjIdni/68YCmhqc=%27 ”
改成“http://dvlshop.lechange.com/index.php/wap/?client_id=lc_mall_m&redirect_uri=https%3A%2F%2Fdvlshop.lechange.com%2Fopenapi%2Ftrustlogin_api%2Fparse%2Fwap_trustlogin_lecheng%2Fcallback&=code&scope=read&state=http%3A%2F%2Fdvlshop.lechange.com%2Findex.php%2Fwap&user=token%2Flcid_9f9lmo2u6i7hkl6t6eaodn2blmg5jbsg&expire=1514191636&source_type=lc_app&nonce=cdizHO6uvSx5JK79Kmtz5RBpSi0ROhpF&signature=VeCceYCWDE6BZjIdni/68YCmhqc=%27”
具體條件是:
- 先判斷是否有source_type=lc_app;
- 再判斷是否有response_type;
- 如果以上兩個都滿足,將“response_type”改成“+auto+”;
各位看官,我理解你們此時不想繼續看下去的心情,其實我當初看着那麼一大坨uri心裏也直犯鬧,但是沒辦法,“食君之祿,分君之憂”,我只能耐着性子一個一個的拆開,還別說,拆開的話就清晰許多了,如下:
http://dvlshop.lechange.com/index.php/wap/?
client_id=lc_mall_m&
redirect_uri=https%3A%2F%2Fdvlshop.lechange.com%2Fopenapi%2Ftrustlogin_api%2Fparse%2Fwap_trustlogin_lecheng%2Fcallback&
response_type=code& #滿足條件的話把這個改成+auto+
scope=read&
state=http%3A%2F%2Fdvlshop.lechange.com%2Findex.php%2Fwap&
user=token%2Flcid_9f9lmo2u6i7hkl6t6eaodn2blmg5jbsg&
expire=1514191636&
source_type=lc_app&
nonce=cdizHO6uvSx5JK79Kmtz5RBpSi0ROhpF&signature=VeCceYCWDE6BZjIdni/68YCmhqc=%27
開始操作
針對這次需求我的計劃是這樣的:把原地址看成"$1+ response_type +$2"這樣的一個樣式,確定$1和$2,然後rewrite成"$1+ +auto+ +$2"不就搞定了麼? 於是乎我就憑着我那二把刀的nginx技術開始動手。折騰了大約半個小時,拿出來這樣一個配置:
location ~ .*\.php.*
{
include php_fcgi.conf;
include pathinfo.conf;
set $flag "0";
if ( $request_uri ~ "source_type=lc_app" ) {
set $flag "1";
}
if ( $request_uri ~ "(.*)response_type(.*)" ){
set $Flag "$flag$flag";
set $id $1;
set $query $2;
}
if ($Flag = "11"){ #注意這個地方是11
set $flag "0";
rewrite ^.*$ http://dvlshop.lechange.com/index.php/wap/$id$query last; #前面那一段是寫死的
}
}
但是很不幸,nginx -s reload
之後的結果是“$1+$2+$1+ response_type +$2”的格式(地址太長太噁心了,我就不寫了)。
然後在arstercz大神的指點下,把那句rewrite改成了return 301 http://dvlshop.lechange.com/index.php/wap/?$id$query;
。就達到了效果。
原因確定
後來追尋原因,原來是: rewrite後面接的$uri不需要$args,因爲$args會被自動帶過來。而return的則會丟失$args,需要手動補上$args。而我上面的$1,$2恰巧就是$args,所以用rewrite的話就會重複。舉個例子,比如請求"http://localhost/?a=1" 想被 301 到"https://localhost/?a=1?a=1」" ,要麼
server {
listen 80;
rewrite / https://$host$uri permanent;
}
要麼就
server {
listen 80;
return 301 https://$host$request_uri;
}
補充說明
PS,這裏補充一下uri、request_uri、document_uri之間的區別:
- $request_uri: /stat.php?id=1585378&web_id=1585378
- $uri: /stat.php (不帶?後面)
- $document_uri: /stat.php (與uri完全相同)
最後的最後,如果您覺得本文對您升職加薪有幫助,那麼請不吝贊助之手,刷一下下面的二維碼,贊助本人繼續寫更多的博文!