Linux下Nginx服務Rewrite和Proxy_Pass

Nginx_Rewrite

一、介紹

  1. Rewrite根據nginx提供的全局變量或自己設置的變量,結合正則表達式和標誌位實現url重寫和者重定向。
  2. Rewrite和location類似,都可以實現跳轉,區別是rewrite是在同一域名內更改url,而location是對同類型匹配路徑做控制訪問,或者proxy_pass代理到其他服務器。
  3. Rewrite和location執行順序:
    • 執行server下的rewrite
    • 執行location匹配
    • 執行location下的rewrite

二、語法和參數說明

1.rewrite語法格式

rewrite        <regex>        <replacement>        <flag>;
 關鍵字        正則表達式         代替的內容         重寫類型

Rewrite:一般都是rewrite
Regex:可以是字符串或者正則來表示想要匹配的目標URL
Replacement:將正則匹配的內容替換成replacement
Flag:flag標示,重寫類型:
  - last:本條規則匹配完成後,繼續向下匹配新的location URI規則;相當於Apache裏德(L)標記,表示完成rewrite,瀏覽器地址欄URL地址不變;一般寫在server和if中;
  - break:本條規則匹配完成後,終止匹配,不再匹配後面的規則,瀏覽器地址欄URL地址不變;一般使用在location中;
  - redirect:返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址;
  - permanent:返回301永久重定向,瀏覽器地址欄會顯示跳轉後的URL地址;
server {
  # 訪問 /last.html 的時候,頁面內容重寫到 /index.html 中,並繼續後面的匹配,瀏覽器地址欄URL地址不變
  rewrite /last.html /index.html last;

  # 訪問 /break.html 的時候,頁面內容重寫到 /index.html 中,並停止後續的匹配,瀏覽器地址欄URL地址不變;
  rewrite /break.html /index.html break;

  # 訪問 /redirect.html 的時候,頁面直接302定向到 /index.html中,瀏覽器地址URL跳爲index.html
  rewrite /redirect.html /index.html redirect;

  # 訪問 /permanent.html 的時候,頁面直接301定向到 /index.html中,瀏覽器地址URL跳爲index.html
  rewrite /permanent.html /index.html permanent;

  # 把 /html/*.html => /post/*.html ,301定向
  rewrite ^/html/(.+?).html$ /post/$1.html permanent;

  # 把 /search/key => /search.html?keyword=key
  rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent;

  # 把當前域名的請求,跳轉到新域名上,域名變化但路徑不變
  rewrite ^/(.*) http://www.jd.com/$1 permanent;
  }

2、IF判斷和內置全局環境變量

if (表達式) {
}

#當表達式只是一個變量時,如果值爲空或任何以0開頭的字符串都會當做false直接比較變量和內容時,使用=或!=~正則表達式匹配,~*不區分大小寫的匹配,!~區分大小寫的不匹配
$args :這個變量等於請求行中的參數,同$query_string
$content_length : 請求頭中的Content-length字段。
$content_type : 請求頭中的Content-Type字段。
$document_root : 當前請求在root指令中指定的值。
$host : 請求主機頭字段,否則爲服務器名稱。
$http_user_agent : 客戶端agent信息
$http_cookie : 客戶端cookie信息
$limit_rate : 這個變量可以限制連接速率。
$request_method : 客戶端請求的動作,通常爲GET或POST。
$remote_addr : 客戶端的IP地址。
$remote_port : 客戶端的端口。
$remote_user : 已經經過Auth Basic Module驗證的用戶名。
$request_filename : 當前請求的文件路徑,由root或alias指令與URI請求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 請求使用的協議,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服務器地址,在完成一次系統調用後可以確定這個值。
$server_name : 服務器名稱。
$server_port : 請求到達服務器的端口號。
$request_uri : 包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。
$uri : 不帶請求參數的當前URI,$uri不包含主機名,如”/foo/bar.html”。
$document_uri : 與$uri相同。

例子:
URL:http://localhost:81/download/stat.php?id=1585378&web_id=1585378
Server_Dir:/var/www/html
$host:localhost
$server_port:81
$request_uri:/download/stat.php?id=1585378&web_id=1585378
$document_uri:/download/stat.php
$document_root:/var/www/html
$request_filename:/var/www/html/download/stat.php

# 如果文件不存在則返回400
if (!-f $request_filename) {
    return 400;
}

# 如果host是www.360buy.com,則301到www.jd.com中
if ( $host != "www.jd.com" ){
    rewrite ^/(.*)$ https://www.jd.com/$1 permanent;
}

# 如果請求類型是POST則返回405,return不能返回301,302
if ($request_method = POST) {
    return 405;
}

# 如果參數中有 a=1 則301到指定域名
if ($args ~ a=1) {
    rewrite ^ http://example.com/ permanent;
}
- 文件名及參數重寫
 location = /index.html {
 # 修改默認值爲
 set $name test;

 # 如果參數中有 name=xx 則使用該值
 if ($args ~* name=(\w+?)(&|$)) {
     set $name $1;
 }

 # permanent 301重定向
 rewrite ^ /$name.html permanent;
}
- 隱藏真實目錄
server {
  root /var/www/html;
  # 用 /html_test 來掩飾 html
  location / {
      # 使用break拿一旦匹配成功則忽略後續location
      rewrite /html_test /html break;
  }

  # 訪問真實地址直接報沒權限
  location /html {
      return 403;
  }
}
- 禁止指定IP訪問
 location / {
        if ($remote_addr = 192.168.1.253) {
                return 403;
        }
 }
- 如果請求的文件不存在,則反向代理到localhost 。這裏的break也是停止繼續rewrite
if (!-f $request_filename){
    break;
    proxy_pass http://127.0.0.1;
}
- 對/images/bla_500x400.jpg文件請求,重寫到/resizer/bla.jpg?width=500&height=400地址,並會繼續嘗試匹配location。
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;

Proxy_Pass

Proxy_pass反向代理,用的是nginx的Proxy模塊

第一種:
location /proxy/ {
    proxy_pass http://127.0.0.1/;
}
代理到URL:http://127.0.0.1/test.html

第二種:
location /proxy/ {
    proxy_pass http://127.0.0.1;  #少/
}
代理到URL:http://127.0.0.1/proxy/test.html

第三種:
location /proxy/ {
    proxy_pass http://127.0.0.1/aaa/;
}
代理到URL:http://127.0.0.1/aaa/test.html

第四種(相對於第三種,最後少一個 / )
location /proxy/ {
    proxy_pass http://127.0.0.1/aaa;
}
代理到URL:http://127.0.0.1/aaatest.html
- proxy_set_header  Host  $host;  作用web服務器上有多個站點時,用該參數header來區分反向代理哪個域名。比如下邊的代碼舉例。
- proxy_set_header X-Forwarded-For  $remote_addr; 作用是後端服務器上的程序獲取訪客真實IP,從該header頭獲取。部分程序需要該功能。
- Proxy_pass配合upstream實現負載均衡
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    upstream core_tomcat {
      server 192.168.1.253:80      weight=5  max_fails=3 fail_timeout=30;
      server 192.168.1.252:80      weight=1  max_fails=3 fail_timeout=30;
      server 192.168.1.251:80      backup;
    }

    server {
        listen       80;
        server_name  www.jd.com;
        location /web {
            proxy_pass http://core_tomcat;
            proxy_set_header  Host  $host;
        }
    }
 }

參考文檔:

https://www.jianshu.com/p/10ecc107b5ee

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