1. 程式人生 > 其它 >立Flag 學習Ng - Location&Rewrite進階

立Flag 學習Ng - Location&Rewrite進階

技術標籤:分散式#nginxnginx

立Flag 學習Ng - Location&Rewrite進階

  • Location&Rewrite進階
  • ng 解決瀏覽器跨域問題

Location&Rewrite進階

這裡要先明確一個概念:

nginx執行階段:

  • rewrite階段(location、rewrite)
  • access階段
  • content階段

這裡要注意的是 ng是按照階段執行的,而不是按照配置檔案的程式碼順序(就是配置檔案配置的順序)

location= / {
    set $a 32;
    echo $a;

    set $a 64;
    echo $a;
}

上面程式碼中使用 set和echo命令。要知道set是屬於access階段 echo屬於content階段。所以這裡最後輸出的都是64

Nginx執行過程

以下面的url為例:

http://127.0.0.1:8081/jimmy/learnNignx.html?a=0

可以拆分為如下內容:

ip/域名+埠+path+param

127.0.0.1 + 8081 + /jimmy/learnNignx.html + a=0

匹配過程:

  • 域名(ip)+埠 定位虛擬主機(server)
  • path與location部分匹配, path = 匹配path(path1) + 剩餘path(path2)
  • 當遇到root則在目錄裡找path1+path2路徑,遇到alias
    則在目錄裡找path2路徑。如果 url是以/結尾則執行index(ng認為url指向的是一個資料夾)
  • 當遇到反向代理 proxy_pass 則需要判斷 proxy_pass 設定的值
    • 當 proxy_pass= ip:port 則 轉發ip+埠+path1+path2路徑
    • 當 proxy_pass= ip:port/ 則 轉發ip+埠+path2路徑
  • 當然如果遇到rewirte則根據正則匹配如果命中則執行rewrite指令

root&alias & index 命令

  • root指檔案根目錄,沒有指定的時候預設是 ng目錄下的 html/
  • alias 玩過資料庫的同學大概應該能理解,其實就是將 location匹配的路徑進行替換
  • index指的是當url傳遞來的是一個資料夾的情況則預設訪問的index
location /a.html {
	root   html/static/;
}
location /b.html {
	root   html/static/;
}

location / {
    root   html/static;
    index  index.html index.htm;
}

location ^~ /cors {
    alias   html/cors;
    index  cors.html;
}

if指令

if (condition) {...}

當表示式只是一個變數時,如果值為空或任何以0開頭的字串都會當做false
直接比較變數和內容時,使用=或!=
~  正則表示式匹配
~* 不區分大小寫的匹配
!~  區分大小寫的不匹配
-f和!-f  用來判斷是否存在檔案
-d和!-d  用來判斷是否存在目錄
-e和!-e  用來判斷是否存在檔案或目錄
-x和!-x  用來判斷檔案是否可執行

###--==-0-==-0-=0=-###

# 如果user_agent包含"MSIE",rewrite請求到/msid/目錄下
if ($http_user_agent ~ MSIE) {
	rewrite ^(.*)$ /msie/$1 break;
} 

# 如果cookie匹配正則,設定變數$id等於正則引用部分
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
	set $id $1;
} 

# 如果提交方法為POST,則返回狀態405(Method not allowed)。return不能返回301,302
if ($request_method = POST) {
	return 405;
} 

# 限速,$slow可以通過 set 指令設定
if ($slow) {
	limit_rate 10k;
} 

# 如果請求的檔名不存在,則反向代理到localhost 。這裡的break也是停止rewrite檢查
if (!-f $request_filename){
    break;
    proxy_pass http://127.0.0.1;
} 

# 如果query string中包含"post=140",永久重定向到example.com
if ($args ~ post=140){
	rewrite ^ http://example.com/ permanent;
} 

#禁止chrome訪問
if ($http_user_agent ~ Chrome) {
    return 503;
}

# 防盜鏈
location ~* \.(gif|jpg|png|swf|flv)$ {
	valid_referers none blocked www.jim.com www.jimmy.com;
    if ($invalid_referer) {
    	return 404;
    } 
}

常見的全域性變數

  • KaTeX parse error: Expected 'EOF', got '#' at position 8: 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”。

  • u r i : 不 帶 請 求 參 數 的 當 前 U R I , uri : 不帶請求引數的當前URI, uriURIuri不包含主機名,如”/foo/bar.html”。

  • d o c u m e n t u r i : 與 document_uri : 與 documenturiuri相同。

栗子:

http://localhost:88/test1/test2/test.php
$host:localhost
$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

這裡囉嗦下,ng是沒有 else語句的,只有if語句,且條件為正則表示式,命中則進入,未命中則不進入。

ng 解決瀏覽器跨域問題

什麼是瀏覽器跨域? TP去知乎看

配置如下:

server {
        listen       80;
        server_name  static.enjoy.com;
	
	 #是否允許請求帶有驗證資訊
     add_header Access-Control-Allow-Credentials true;
     #允許跨域訪問的域名,可以是一個域的列表,也可以是萬用字元*
     add_header Access-Control-Allow-Origin  *;
     #允許指令碼訪問的返回頭
     add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';
     #允許使用的請求方法,以逗號隔開
     add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
     #允許自定義的頭部,以逗號隔開,大小寫不敏感
     add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';
     #P3P支援跨域cookie操作
     add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';

    location / {
    	root   html/static;
    	index  index.html index.htm;
    }
    location /cors {
    	root   html/cors;
    	index  cors.html;
    }
}