nginx配置location總結及rewrite規則寫法

<div class="post-body" itemprop="articleBody" style="opacity: 1; display: block; transform: translateY(0px);">php

<h1 id="1-location正則寫法"><a href="#1-location正則寫法" class="headerlink" title="1. location正則寫法"></a>1. location正則寫法</h1><p>一個示例:</p>

<figure class="highlight plain"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line">location = / {</span><br><span class="line"> # 精確匹配 / ,主機名後面不能帶任何字符串</span><br><span class="line"> [ configuration A ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location / {</span><br><span class="line"> # 由於全部的地址都以 / 開頭,因此這條規則將匹配到全部請求</span><br><span class="line"> # 可是正則和最長字符串會優先匹配</span><br><span class="line"> [ configuration B ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location /documents/ {</span><br><span class="line"> # 匹配任何以 /documents/ 開頭的地址,匹配符合之後,還要繼續往下搜索</span><br><span class="line"> # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條</span><br><span class="line"> [ configuration C ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location ~ /documents/Abc {</span><br><span class="line"> # 匹配任何以 /documents/Abc 開頭的地址,匹配符合之後,還要繼續往下搜索</span><br><span class="line"> # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條</span><br><span class="line"> [ configuration CC ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location ^~ /images/ {</span><br><span class="line"> # 匹配任何以 /images/ 開頭的地址,匹配符合之後,中止往下搜索正則,採用這一條。</span><br><span class="line"> [ configuration D ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location ~* \.(gif|jpg|jpeg)$ {</span><br><span class="line"> # 匹配全部以 gif,jpg或jpeg 結尾的請求</span><br><span class="line"> # 然而,全部請求 /images/ 下的圖片會被 config D 處理,由於 ^~ 到達不了這一條正則</span><br><span class="line"> [ configuration E ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location /images/ {</span><br><span class="line"> # 字符匹配到 /images/,繼續往下,會發現 ^~ 存在</span><br><span class="line"> [ configuration F ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location /images/abc {</span><br><span class="line"> # 最長字符匹配到 /images/abc,繼續往下,會發現 ^~ 存在</span><br><span class="line"> # F與G的放置順序是沒有關係的</span><br><span class="line"> [ configuration G ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location ~ /images/abc/ {</span><br><span class="line"> # 只有去掉 config D 纔有效:先最長匹配 config G 開頭的地址,繼續往下搜索,匹配到這一條正則,採用</span><br><span class="line"> [ configuration H ]</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">location ~* /js/.*/\.js</span><br></pre></td></tr></tbody></table></figure> <a id="more"></a> <ul> <li>已<code>=</code>開頭表示精確匹配<br>如 A 中只匹配根目錄結尾的請求,後面不能帶任何字符串。</li> <li><code>^~</code> 開頭表示uri以某個常規字符串開頭,不是正則匹配</li> <li>~ 開頭表示區分大小寫的正則匹配;</li> <li>~* 開頭表示不區分大小寫的正則匹配</li> <li>/ 通用匹配, 若是沒有其它匹配,任何請求都會匹配到</li> </ul> <p>順序 no優先級:<br>(location =) &gt; (location 完整路徑) &gt; (location ^~ 路徑) &gt; (location ~,~* 正則順序) &gt; (location 部分起始路徑) &gt; (/)</p> <p>上面的匹配結果<br>按照上面的location寫法,如下的匹配示例成立:</p> <ul> <li>/ -&gt; config A<br>精確徹底匹配,即便/index.html也匹配不了</li> <li>/downloads/download.html -&gt; config B<br>匹配B之後,往下沒有任何匹配,採用B</li> <li>/images/1.gif -&gt; configuration D<br>匹配到F,往下匹配到D,中止往下</li> <li>/images/abc/def -&gt; config D<br>最長匹配到G,往下匹配D,中止往下<br>你能夠看到 任何以/images/開頭的都會匹配到D並中止,FG寫在這裏是沒有任何意義的,H是永遠輪不到的,這裏只是爲了說明匹配順序</li> <li>/documents/document.html -&gt; config C<br>匹配到C,往下沒有任何匹配,採用C</li> <li>/documents/1.jpg -&gt; configuration E<br>匹配到C,往下正則匹配到E</li> <li>/documents/Abc.jpg -&gt; config CC<br>最長匹配到C,往下正則順序匹配到CC,不會往下到E</li> </ul> <h2 id="實際使用建議"><a href="#實際使用建議" class="headerlink" title="實際使用建議"></a>實際使用建議</h2><figure class="highlight plain"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">因此實際使用中,我的以爲至少有三個匹配規則定義,以下:</span><br><span class="line">#直接匹配網站根,經過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。</span><br><span class="line">#這裏是直接轉發給後端應用服務器了,也能夠是一個靜態首頁</span><br><span class="line"># 第一個必選規則</span><br><span class="line">location = / {</span><br><span class="line"> proxy_pass http://tomcat:8080/index</span><br><span class="line">}</span><br><span class="line"># 第二個必選規則是處理靜態文件請求,這是nginx做爲http服務器的強項</span><br><span class="line"># 有兩種配置模式,目錄匹配或後綴匹配,任選其一或搭配使用</span><br><span class="line">location ^~ /static/ {</span><br><span class="line"> root /webroot/static/;</span><br><span class="line">}</span><br><span class="line">location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {</span><br><span class="line"> root /webroot/res/;</span><br><span class="line">}</span><br><span class="line">#第三個規則就是通用規則,用來轉發動態請求到後端應用服務器</span><br><span class="line">#非靜態文件請求就默認是動態請求,本身根據實際把握</span><br><span class="line">#畢竟目前的一些框架的流行,帶.php,.jsp後綴的狀況不多了</span><br><span class="line">location / {</span><br><span class="line"> proxy_pass http://tomcat:8080/</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure> <p><a href="http://tengine.taobao.org/book/chapter_02.html" target="_blank" rel="noopener">http://tengine.taobao.org/book/chapter_02.html</a><br><a href="http://nginx.org/en/docs/http/ngx_http_rewrite_module.html" target="_blank" rel="noopener">http://nginx.org/en/docs/http/ngx_http_rewrite_module.html</a></p> <h1 id="2-Rewrite規則"><a href="#2-Rewrite規則" class="headerlink" title="2. Rewrite規則"></a>2. Rewrite規則</h1><p>rewrite功能就是,使用nginx提供的全局變量或本身設置的變量,結合正則表達式和標誌位實現url重寫以及重定向。rewrite只能放在server{},location{},if{}中,而且只能對域名後邊的除去傳遞的參數外的字符串起做用,例如 <code>http://seanlook.com/a/we/index.php?id=1&amp;u=str</code> 只對/a/we/index.php重寫。語法<code>rewrite regex replacement [flag];</code></p> <p>若是相對域名或參數字符串起做用,可使用全局變量匹配,也可使用proxy_pass反向代理。</p> <p>代表看rewrite和location功能有點像,都能實現跳轉,主要區別在於rewrite是在同一域名內更改獲取資源的路徑,而location是對一類路徑作控制訪問或反向代理,能夠proxy_pass到其餘機器。不少狀況下rewrite也會寫在location裏,它們的執行順序是:</p> <ol> <li>執行server塊的rewrite指令</li> <li>執行location匹配</li> <li>執行選定的location中的rewrite指令</li> </ol> <p>若是其中某步URI被重寫,則從新循環執行1-3,直到找到真實存在的文件;循環超過10次,則返回500 Internal Server Error錯誤。</p> <h2 id="2-1-flag標誌位"><a href="#2-1-flag標誌位" class="headerlink" title="2.1 flag標誌位"></a>2.1 flag標誌位</h2><ul> <li><code>last</code> : 至關於Apache的[L]標記,表示完成rewrite</li> <li><code>break</code> : 中止執行當前虛擬主機的後續rewrite指令集</li> <li><code>redirect</code> : 返回302臨時重定向,地址欄會顯示跳轉後的地址</li> <li><code>permanent</code> : 返回301永久重定向,地址欄會顯示跳轉後的地址</li> </ul> <p>由於301和302不能簡單的只返回狀態碼,還必須有重定向的URL,這就是return指令沒法返回301,302的緣由了。這裏 last 和 break 區別有點難以理解:</p> <ol> <li>last通常寫在server和if中,而break通常使用在location中</li> <li>last不終止<em>重寫後</em>的url匹配,即新的url會再從server走一遍匹配流程,而break終止重寫後的匹配</li> <li>break和last都能組織繼續執行後面的rewrite指令</li> </ol> <h2 id="2-2-if指令與全局變量"><a href="#2-2-if指令與全局變量" class="headerlink" title="2.2 if指令與全局變量"></a>2.2 if指令與全局變量</h2><p><strong>if判斷指令</strong><br>語法爲<code>if(condition){...}</code>,對給定的條件condition進行判斷。若是爲真,大括號內的rewrite指令將被執行,if條件(conditon)能夠是以下任何內容:</p> <ul> <li>當表達式只是一個變量時,若是值爲空或任何以0開頭的字符串都會當作false</li> <li>直接比較變量和內容時,使用<code>=</code>或<code>!=</code></li> <li><code>~</code>正則表達式匹配,<code>~*</code>不區分大小寫的匹配,<code>!~</code>區分大小寫的不匹配</li> </ul> <p><code>-f</code>和<code>!-f</code>用來判斷是否存在文件<br><code>-d</code>和<code>!-d</code>用來判斷是否存在目錄<br><code>-e</code>和<code>!-e</code>用來判斷是否存在文件或目錄<br><code>-x</code>和<code>!-x</code>用來判斷文件是否可執行</p> <p>例如:<br></p><figure class="highlight plain"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">if ($http_user_agent ~ MSIE) {</span><br><span class="line"> rewrite ^(.*)$ /msie/$1 break;</span><br><span class="line">} //若是UA包含"MSIE",rewrite請求到/msid/目錄下</span><br><span class="line"></span><br><span class="line">if ($http_cookie ~* "id=([^;]+)(?:;|$)") {</span><br><span class="line"> set $id $1;</span><br><span class="line"> } //若是cookie匹配正則,設置變量$id等於正則引用部分</span><br><span class="line"></span><br><span class="line">if ($request_method = POST) {</span><br><span class="line"> return 405;</span><br><span class="line">} //若是提交方法爲POST,則返回狀態405(Method not allowed)。return不能返回301,302</span><br><span class="line"></span><br><span class="line">if ($slow) {</span><br><span class="line"> limit_rate 10k;</span><br><span class="line">} //限速,$slow能夠經過 set 指令設置</span><br><span class="line"></span><br><span class="line">if (!-f $request_filename){</span><br><span class="line"> break;</span><br><span class="line"> proxy_pass http://127.0.0.1;</span><br><span class="line">} //若是請求的文件名不存在,則反向代理到localhost 。這裏的break也是中止rewrite檢查</span><br><span class="line"></span><br><span class="line">if ($args ~ post=140){</span><br><span class="line"> rewrite ^ http://example.com/ permanent;</span><br><span class="line">} //若是query string中包含"post=140",永久重定向到example.com</span><br><span class="line"></span><br><span class="line">location ~* \.(gif|jpg|png|swf|flv)$ {</span><br><span class="line"> valid_referers none blocked www.jefflei.com www.leizhenfang.com;</span><br><span class="line"> if ($invalid_referer) {</span><br><span class="line"> return 404;</span><br><span class="line"> } //防盜鏈</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p></p> <p><strong>全局變量</strong><br>下面是能夠用做if判斷的全局變量</p> <ul> <li><code>$args</code> : #這個變量等於請求行中的參數,同<code>$query_string</code></li> <li><code>$content_length</code> : 請求頭中的Content-length字段。</li> <li><code>$content_type</code> : 請求頭中的Content-Type字段。</li> <li><code>$document_root</code> : 當前請求在root指令中指定的值。</li> <li><code>$host</code> : 請求主機頭字段,不然爲服務器名稱。</li> <li><code>$http_user_agent</code> : 客戶端agent信息</li> <li><code>$http_cookie</code> : 客戶端cookie信息</li> <li><code>$limit_rate</code> : 這個變量能夠限制鏈接速率。</li> <li><code>$request_method</code> : 客戶端請求的動做,一般爲GET或POST。</li> <li><code>$remote_addr</code> : 客戶端的IP地址。</li> <li><code>$remote_port</code> : 客戶端的端口。</li> <li><code>$remote_user</code> : 已經通過Auth Basic Module驗證的用戶名。</li> <li><code>$request_filename</code> : 當前請求的文件路徑,由root或alias指令與URI請求生成。</li> <li><code>$scheme</code> : HTTP方法(如http,https)。</li> <li><code>$server_protocol</code> : 請求使用的協議,一般是HTTP/1.0或HTTP/1.1。</li> <li><code>$server_addr</code> : 服務器地址,在完成一次系統調用後能夠肯定這個值。</li> <li><code>$server_name</code> : 服務器名稱。</li> <li><code>$server_port</code> : 請求到達服務器的端口號。</li> <li><code>$request_uri</code> : 包含請求參數的原始URI,不包含主機名,如:」/foo/bar.php?arg=baz」。</li> <li><code>$uri</code> : 不帶請求參數的當前URI,$uri不包含主機名,如」/foo/bar.html」。</li> <li><code>$document_uri</code> : 與$uri相同。</li> </ul> <p>例:<code>http://localhost:88/test1/test2/test.php</code><br>$host:localhost<br>$server_port:88<br>$request_uri:<a href="http://localhost:88/test1/test2/test.php" target="_blank" rel="noopener">http://localhost:88/test1/test2/test.php</a><br>$document_uri:/test1/test2/test.php<br>$document_root:/var/www/html<br>$request_filename:/var/www/html/test1/test2/test.php</p> <h2 id="2-3-經常使用正則"><a href="#2-3-經常使用正則" class="headerlink" title="2.3 經常使用正則"></a>2.3 經常使用正則</h2><ul> <li><code>.</code> : 匹配除換行符之外的任意字符</li> <li><code>?</code> : 重複0次或1次</li> <li><code>+</code> : 重複1次或更屢次</li> <li><code>*</code> : 重複0次或更屢次</li> <li><code>\d</code> :匹配數字</li> <li><code>^</code> : 匹配字符串的開始</li> <li><code>$</code> : 匹配字符串的介紹</li> <li><code>{n}</code> : 重複n次</li> <li><code>{n,}</code> : 重複n次或更屢次</li> <li><code>[c]</code> : 匹配單個字符c</li> <li><code>[a-z]</code> : 匹配a-z小寫字母的任意一個</li> </ul> <p>小括號<code>()</code>之間匹配的內容,能夠在後面經過<code>$1</code>來引用,<code>$2</code>表示的是前面第二個<code>()</code>裏的內容。正則裏面容易讓人困惑的是<code>\</code>轉義特殊字符。</p> <h2 id="2-4-rewrite實例"><a href="#2-4-rewrite實例" class="headerlink" title="2.4 rewrite實例"></a>2.4 rewrite實例</h2><p><em>例1</em>:<br></p><figure class="highlight plain"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">http {</span><br><span class="line"> # 定義image日誌格式</span><br><span class="line"> log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;</span><br><span class="line"> # 開啓重寫日誌</span><br><span class="line"> rewrite_log on;</span><br><span class="line"></span><br><span class="line"> server {</span><br><span class="line"> root /home/www;</span><br><span class="line"></span><br><span class="line"> location / {</span><br><span class="line"> # 重寫規則信息</span><br><span class="line"> error_log logs/rewrite.log notice;</span><br><span class="line"> # 注意這裏要用‘’單引號引發來,避免{}</span><br><span class="line"> rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;</span><br><span class="line"> # 注意不能在上面這條規則後面加上「last」參數,不然下面的set指令不會執行</span><br><span class="line"> set $image_file $3;</span><br><span class="line"> set $image_type $4;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> location /data {</span><br><span class="line"> # 指定針對圖片的日誌格式,來分析圖片類型和大小</span><br><span class="line"> access_log logs/images.log mian;</span><br><span class="line"> root /data/images;</span><br><span class="line"> # 應用前面定義的變量。判斷首先文件在不在,不在再判斷目錄在不在,若是還不在就跳轉到最後一個url裏</span><br><span class="line"> try_files /$arg_file /image404.html;</span><br><span class="line"> }</span><br><span class="line"> location = /image404.html {</span><br><span class="line"> # 圖片不存在返回特定的信息</span><br><span class="line"> return 404 "image not found\n";</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p></p> <p>對形如<code>/images/ef/uh7b3/test.png</code>的請求,重寫到<code>/data?file=test.png</code>,因而匹配到<code>location /data</code>,先看<code>/data/images/test.png</code>文件存不存在,若是存在則正常響應,若是不存在則重寫tryfiles到新的image404 location,直接返回404狀態碼。</p> <p><em>例2</em>:<br></p><figure class="highlight plain"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&amp;height=$3? last;</span><br></pre></td></tr></tbody></table></figure><p></p> <p>對形如<code>/images/bla_500x400.jpg</code>的文件請求,重寫到<code>/resizer/bla.jpg?width=500&amp;height=400</code>地址,並會繼續嘗試匹配location。</p> <p><em>例3</em>:<br>見 <a href="http://seanlook.com/2015/05/28/nginx-ssl">ssl部分頁面加密</a> 。</p> <p><strong>參考</strong></p> <ul> <li><a href="http://www.nginx.cn/216.html" target="_blank" rel="noopener">http://www.nginx.cn/216.html</a></li> <li><a href="http://www.ttlsa.com/nginx/nginx-rewriting-rules-guide/" target="_blank" rel="noopener">http://www.ttlsa.com/nginx/nginx-rewriting-rules-guide/</a></li> <li>老僧系列nginx之rewrite規則快速上手</li> <li><a href="http://fantefei.blog.51cto.com/2229719/919431" target="_blank" rel="noopener">http://fantefei.blog.51cto.com/2229719/919431</a> </li> </ul>css

</div>
相關文章
相關標籤/搜索