記一次配置rewrite和return的經歷

前言與需求

自動電商平臺歸屬了大數據研究院之後,我又恢復了那個“把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”

具體條件是:

  1. 先判斷是否有source_type=lc_app;
  2. 再判斷是否有response_type;
  3. 如果以上兩個都滿足,將“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完全相同)

最後的最後,如果您覺得本文對您升職加薪有幫助,那麼請不吝贊助之手,刷一下下面的二維碼,贊助本人繼續寫更多的博文!
記一次配置rewrite和return的經歷

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章