首頁  >  文章  >  後端開發  >  nginx location及rewrite的寫法說明

nginx location及rewrite的寫法說明

WBOY
WBOY原創
2016-07-30 13:31:071161瀏覽
location正規寫法一個範例:location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求# 但是正则和最长字符串会优先匹配 [ configuration B ] } location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration C ] } location ~ /documents/Abc { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration CC ] } location ^~ /images/ { # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。 [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { # 匹配所有以 gif,jpg或jpeg 结尾的请求# 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则 [ configuration E ] } location /images/ { # 字符匹配到 /images/,继续往下,会发现 ^~ 存在 [ configuration F ] } location /images/abc { # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在# F与G的放置顺序是没有关系的 [ configuration G ] } location ~ /images/abc/ { # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用 [ configuration H ] } location ~* /js/.*/\.js
  • =開頭表示精確符合
    如 A 中只符合根目錄結尾的請求,後面不能帶任何字串。
  • ^~ 開頭表示uri以某個常規字串開頭,不是正則匹配
  • ~ 開頭表示區分大小寫的正則匹配;
  • ~* 開頭表示不區分大小寫的正則匹配
  • / 通用匹配, 如果沒有其它匹配,任何請求都會匹配到
  • 順序no優先權:
    (location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location部分起始路徑) > (/)上面的匹配結果
    按照上面的location寫法,以下的匹配示例成立:
  • / -> config A
    精確完全匹配,即使/index.html也匹配不了
  • /downloads/download.html -> config B
    匹配B以後,往下沒有任何匹配,採用B
  • /images/1.gif -> configuration D
    匹配到F,往下匹配到D,停止往下
  • /images/abc/def -> config D
    最長匹配到G,往下匹配D,停止往下
    你可以看到任何以/images/開頭的都會匹配到D並停止,FG寫在這裡是沒有意義的,H是永遠輪不到的,這裡只是為了說明匹配順序
  • /documents/document.html -> config C
    匹配到C,往下沒有任何匹配,採用C
  • /documents/ 1.jpg -> configuration E
    匹配到C,往下正則匹配到E
  • /documents/Abc.jpg -> config CC
    最長匹配到C,往下正則順序匹配到CC,不會往下到E
  • 實際使用建議所以实际使用中,个人觉得至少有三个匹配规则定义,如下: #直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。#这里是直接转发给后端应用服务器了,也可以是一个静态首页# 第一个必选规则 location = / { proxy_pass http://tomcat:8080/index } # 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用 location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; } #第三个规则就是通用规则,用来转发动态请求到后端应用服务器#非静态文件请求就默认是动态请求,自己根据实际把握#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了 location / { proxy_pass http://tomcat:8080/ } http://tengine.taobao.org/book/chapter_02.html
    http://nginx.org/en/docs/http/ngx_http_rewrite_module.html功能就是,使用nginx提供的全域變數或自己設定的變量,結合正規表示式和標誌位元實作url重寫以及重定向。 rewrite只能放在server{},location{},if{}中,並且只能對網域後邊的除去傳遞的參數外的字串起作用,例如http://seanlook.com/a/we/ index.php?id=1&u=str 只對/a/we/index.php重寫。語法rewrite regex replacement [flag];如果相對網域名稱或參數字串起作用,可以使用全域變數匹配,也可以使用proxy_pass反向代理。 顯示看rewrite和location功能有點像,都能實現跳轉,主要區別在於rewrite是在同一域名內更改獲取資源的路徑,而location是對一類路徑做控制訪問或反向代理,可以proxy_pass到其他機器。很多情況下rewrite也會寫在location裡,它們的執行順序是:
  • 執行server塊的rewrite指令
  • 執行location匹配
  • 執行選定的location中的rewrite指令
  • 如果其中某步URI被重寫,則重新循環執行1-3,直到找到真實存在的文件;循環超過10次,則回傳500 Internal Server Error錯誤。 flag標誌位元
  • last : 相當於Apache的[L]標記,表示完成rewrite
  • break : 停止執行目前虛擬主機的後續指令集
  • 定向,網址列會顯示跳轉後的位址
  • permanent
  •  : 回傳301永久重定向,網址列會顯示跳轉後的位址
  • 因為301和302不能簡單的只回傳狀態碼,還必須有重定向的URL,這就是return指令無法回傳301,302的原因了。這裡last 和break 區別有點難以理解:
  • last一般寫在server和if中,而break一般使用在location中last不終止
  • 重寫後
  • 的url匹配,即新的url會再從server走一遍配對流程,而break終止重寫後的配對
  • break和last都能組織繼續執行後面的rewrite指令
  • if指令與全域變數
  • if判斷指令語法為全域變數
    if判斷指令語法為全域變數 {...}🎜,對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執行,if條件(conditon)可以是下列任何內容:🎜
  • 当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
  • 直接比较变量和内容时,使用=或!=
  • ~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的不匹配
  • -f和!-f用来判断是否存在文件
    -d和!-d用来判断是否存在目录
    -e和!-e用来判断是否存在文件或目录
    -x和!-x用来判断文件是否可执行例如:if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1break; } //如果UA包含"MSIE",rewrite请求到/msid/目录下 if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set$id$1; } //如果cookie匹配正则,设置变量$id等于正则引用部分 if ($request_method = POST) { return405; } //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302if ($slow) { limit_rate 10k; } //限速,$slow可以通过 set 指令设置 if (!-f$request_filename){ break; proxy_pass http://127.0.0.1; } //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查 if ($args ~ post=140){ rewrite ^ http://example.com/ permanent; } //如果query string中包含"post=140",永久重定向到example.com location ~* \.(gif|jpg|png|swf|flv)$ { valid_referers none blocked www.jefflei.com www.leizhenfang.com; if ($invalid_referer) { return404; } //防盗链 } 全局变量
    下面是可以用作if判断的全局变量
  • $args : #這個變數等於請求行中的參數,同$query_string
  • $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相同。
  • 例:http://localhost:88/test1/test2/test.php
    $host:localhost
    $server_port:88
    $request_uri:http://localhost:88/test$server_port:88
    $request_uri:http://localhost:88/test1/test2/test. php
    $document_uri:/test1/test2/test.php
    $document_root:/var/www/html$request_filename:/var/www/html/test1/test2/test.php常用正規
  •  : 符合換行符以外的任意字元
  • ?
  •  : 重複0次或1次
  • +
  •  : 重複1次或更多次
  • +
  •  : 重複1次或更多次 d :配對數字^ : 配對字串的開始$ : 配對字串的介紹{n} : 重複重複次或更多🎜🎜[c]🎜 : 任意一個字 c🎜🎜🎜[a-z]🎜 : 符合a-z小寫字母的任一個🎜🎜🎜小號🎜(),後面可以匹配的內容,後面可以在後面配對的內容,可以在後面配對的內容,可以在後面配對的內容,可以在後面配對透過🎜$1🎜來引用,🎜$2🎜表示的是前面第二個🎜()🎜裡的內容。正規裡面容易讓人困惑的是🎜🎜轉義特殊字符。 🎜🎜rewrite實例🎜🎜🎜例1🎜:🎜http { # 定义image日志格式log_format imagelog '[$time_local] '$image_file' '$image_type' '$body_bytes_sent' '$status; # 开启重写日志rewrite_logon; server { root /home/www; location / { # 重写规则信息error_log logs/rewrite.log notice; # 注意这里要用‘’单引号引起来,避免{}rewrite'^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4; # 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行set$image_file$3; set$image_type$4; } location /data { # 指定针对图片的日志格式,来分析图片类型和大小access_log logs/images.log mian; root /data/images; # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里try_files /$arg_file /image404.html; } location = /image404.html { # 图片不存在返回特定的信息return404"image not found\n"; } } 对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,于是匹配到location /data,先看/data/images/test.png文件存不存在,如果存在则正常响应,如果不存在则重写tryfiles到新的image404 location,直接返回404状态码。例2rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last; 对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。例3
    见 http://seanlook.com/2015/05/28/nginx-ssl ;

    以上就介绍了nginx location及rewrite的写法说明,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

    陳述:
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn