答疑解惑之nginx

試水篇,歡迎各位大佬糾錯👏👏👏👏javascript

本文將講解:css

  • nginx的安裝文件映射
  • nginx命令及常見錯誤的解釋
  • nginx配置文件解析及經常使用變量
  • nginx應用場景
  • location匹配規則
  • rewrite指令部分

nginx簡述與安裝

nginx是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務。html

安裝

Homebrew是macOS系統的軟件包的管理器,能夠用它來安裝nginx:前端

附上Homebrew的官網:https://brew.sh/indexjava

首先安裝Homebrow:linux

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
複製代碼

成功後安裝nginx,終端執行: brew install nginxnginx

Homebrew 會將軟件包安裝到獨立目錄,並將其文件軟連接至/usr/localgit

nginx安裝文件目錄:/usr/local/Cellar/nginx
nginx配置文件目錄:/usr/local/etc/nginx
服務器默認路徑:/usr/local/var/www
複製代碼

當咱們敲下nginx命令時,其實是執行了一個腳本,咱們能夠用which命令是查找命令是否存在,以及命令的存放位置在哪兒github

Mac os 系統(基於Unix系統)通常的應用都會放在/usr/local文件夾下面,/usr文件夾通常是對用戶隱藏的,能夠經過命令訪問。web

這裏能夠看到nginx是指向的一個軟鏈接,最後執行的文件是/usr/local/Cellar/nginx/1.15.9/bin/nginx(能夠經過ll命令查看文件的軟鏈接信息)

簡單說下軟鏈接:軟鏈接相似window的快捷方式,它是能夠跨磁盤塊,目的爲了複用模塊,系統中有不少地方都用到軟鏈接。咱們能夠看到最後執行的腳本文件位於/usr/local/Cellar/nginx/1.15.9/bin/nginx

引伸:軟鏈接跟硬鏈接的區別:www.ibm.com/developerwo…

nginx命令

經常使用nginx命令(管理員權限加sudo):

nginx #打開 nginx
nginx -t #測試配置文件是否有語法錯誤
nginx -s reopen #重啓Nginx
nginx -s reload  #從新加載Nginx配置文件,而後以優雅的方式重啓Nginx
nginx -s stop  #強制中止Nginx服務
nginx -s quit  #優雅地中止Nginx服務(即處理完全部請求後再中止服務)
nginx -c  配置文件地址 #設置配置文件
複製代碼

咱們執行nginx重啓命令有時候會遇到如下錯誤:

nginx: [error] open() "/usr/local/var/run/nginx.pid" failed (2: No such file or directory)
複製代碼

字面大概意思是沒有nginx.pid文件,進到/usr/local/var/run/目錄發現確實沒有這個文件,你們都知道通常解決辦法都是用

sudo nginx -c /usr/local/etc/nginx/nginx.conf
複製代碼

那爲何執行這個命令就有這個文件了呢?

你們都知道 nginx -c 命令是指定配置文件,正常運行以後咱們能夠執行cat /usr/local/var/run/nginx.pid查看該文件的內容,發現內容只有一行數字。

這個數字實際上是該進程的id,這個文件的做用是爲了防止啓動多個進程副本

咱們能夠用ps -ef|grep nginx查看nginx的進程信息:

能夠看到主進程的id跟上面文件內容是同樣的,這個時候可能會產生疑問,爲何會有多個id?

nginx遵循Master-Worker設計模式,是以多進程的方式來工做的,nginx在啓動後,會有一個master進程和多個worker進程,master進程主要用來管理worker進程(因此能夠用kill -QUIT 主進程號等方法來關閉nginx)。

能夠得出結論:當主進程存在時,nginx.pid文件就會存在,內容爲主進程id,當進程關掉時nginx.pid文件也就自動刪除了,因此須要咱們去指定配置文件。

Nginx配置文件解析

//定義nginx運行的用戶(用戶涉及到文件的權限)
 #user nobody;
 //nginx進程數,能夠用ps -ef|grep nginx查看進程
 worker_processes  1;
 //全局錯誤日誌定義類型, Homebrew放在/usr/local/var/log/nginx/error.log
 #error_log logs/error.log;
 #error_log logs/error.log notice;
 #error_log logs/error.log info;
 //進程文件
 #pid logs/nginx.pid; 
 //events模塊來用指定nginx的工做模式及鏈接數上限
 events {
    // 單個進程最大連接數(即接受前端請求的連接數)
    worker_connections  1024;
 }
 
 //設定http服務器()
 http { //這個是協議級別
 	//文件擴展名與文件類型映射表
 	include       mime.types;
 	//默認文件類型
 	default_type  application/octet-stream;
 	//日誌格式定義,變量見下面定義
 	#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 	# '$status $body_bytes_sent "$http_referer" '
 	# '"$http_user_agent" "$http_x_forwarded_for"';
 	//定義訪問日誌目錄,Homebrew放在/usr/local/var/log/nginx/access.log
	# access_log logs/access.log main;
 	//開啓高效文件傳輸模式
 	sendfile      on;
 	//集中發包,提升效率,sendfile on 狀況下才能夠打開
 	#tcp_nopush on;
 	//長連接超時時間
 	keepalive_timeout  65;
 	//開始gzip壓縮,服務器壓縮,瀏覽器解壓
 	#gzip on;
 	 //單個虛擬主機的配置
 	server { //這個是服務器級別
 		//監聽的端口
 		listen       8080;
 		//監聽的服務域名,能夠有多個,用逗號隔開
 		server_name  localhost;
 		//默認編碼
 		#charset koi8-r;
 		//該虛擬主機日誌的存放位置
 		#access_log logs/host.access.log main;
 		//對應的路由展現
 		location / { //這個是請求級別
 		    //文件目錄
 		    root   html;
 		    index  index.html index.htm;
 		}
 		//錯誤頁面
 		error_page   500 502 503 504  /50x.html;
 		location = /50x.html {
 			//相對的路徑存放目錄
 			root   html;
  		}
  	}
  	// 增長配置能夠include其餘配置文件
  	include configarable.conf;
 }
複製代碼

訪問nginx的error.log文件: tail /usr/local/var/log/nginx/error.log (默認查最後十行)

訪問nginx的access.log文件: tail /usr/local/var/log/nginx/access.log (默認查最後十行)

nginx內置變量

$uri                       請求的URI,可能會通過重定向致使跟最初的值有不一樣
$http_user_agent           客戶端信息
$args                      請求參數;
$body_bytes_sent           已發送的消息體字節數
$content_length            header頭信息裏的"Content-Length"
$content_type              header頭信息裏的"Content-Type"
$document_root             針對當前請求的根路徑設置值
$document_uri$uri相同
$host                    請求信息中的"Host",沒有Host行,則等於設置的服務器名;    
$http_cookie               cookie 信息 
$http_referer              來源地址
$limit_rate                對鏈接速率的限制          
$remote_addr               客戶端地址
$remote_port               客戶端端口號
$remote_user               客戶端用戶名,認證用
$request_body              用戶請求主體
$request_body_file         發日後端的本地文件名稱      
$request_filename          當前請求的文件路徑名
$request_method            請求的方法,好比"GET""POST"$request_uri               請求的URI,帶參數   
$server_addr               服務器地址
$server_name               請求到達的服務器名
$server_port               請求到達的服務器端口號
$server_protocol           請求的協議版本,"HTTP/1.0""HTTP/1.1"
複製代碼

nginx的應用場景

  1. 靜態資源web服務器
  2. 代理服務器
  3. 負載均衡

靜態資源服務器

nginx採用的是異步非阻塞的通訊機制(epoll模型),支持更大的併發鏈接.所謂的epoll模型:當事件沒有準備好時,就放入epoll(隊列)裏面。若是有事件準備好了,那麼就去處理;實現由進程循環處理多個準備好的事件,從而實現高併發和輕量級。

預先定義好本地的靜態資源:(後面的例子也會用到這些)

/usr/local/test-img/follow.png,
/usr/local/test-img/403.png,
/usr/local/test-html/forward.html,
/usr/local/test-html/taobao/forward.html,
/usr/local/test-html/taobao/taobao.html,
/usr/local/test-html/taobaowang/taobao.html,
/usr/local/test-html/upstream/1.html,
/usr/local/test-html/upstream/2.html,
/usr/local/test-html/upstream/3.html,
/usr/local/test-html/upstream/4.html
複製代碼

Gzip壓縮

靜態資源就會涉及到Gzip壓縮問題:

syntax:gzip on | off
default:gzip off
context:http, server, if in location
複製代碼

配置語法:

//打開或者關閉gzip壓縮的功能
gzip  on;
// 最小壓縮長度, 被壓縮的內容超過這個長度纔會被壓縮,不然直接輸出
gzip_min_length 1024; 
// 壓縮級別,分爲1-9
gzip_comp_level 2;
// 列出來的內容類型纔會被壓縮,其餘類型的內容不會被壓縮,類型指的是MIME類型
gzip_types text/plain application/x-javascript text/css application/xml text/javascript  image/jpeg image/gif image/png;
// 會在響應頭增長vary:Accept-Encoding,表明已經進行服務端壓縮
gzip_vary on
//設置nginx 服務器是否對後端返回的結果進行gzip壓縮,反向代理的時候有效
gzip_proxine 
// 存放靜態資源的文件路徑
root /usr/local/test-img;
複製代碼

在瀏覽器訪問:http://localhost:9090/follow.png驗證:

開啓壓縮前:

開啓壓縮後:

看到這個表明已經開啓壓縮:

咱們能夠看到文件體積已經變小了

防盜鏈

首先說一下盜鏈,舉個例子:別人把你網站上的圖片連接放到本身的網站上,這樣在訪問別人的網站時,實際上在調用你網站上的圖片,還要用你服務器的流量帶寬。

防盜鏈是基於驗證referer來實現的,referer表示一個網站的請求來源,假裝referer頭部是很是簡單的事情,因此這個模塊只能用於阻止大部分非法請求.咱們應該知道,有些合法的請求是不會帶referer來源頭部的,因此有時候不要拒絕來源頭部(referer)爲空的請求。好比直接在瀏覽器的地址欄中輸入一個資源的URL地址,那麼這種請求是不會包含referer字段的。

nginx防盜鏈指令:

syntax: valid_referers none | blocked | server_names | string...;
default: -
context:server, location
複製代碼

參數解釋:

none:表示來源頭部爲空的狀況
blocked:表示來源頭部不爲空,可是裏面的值被代理或者防火牆刪除了,這些值都不以http:// 或者https:// 開頭。
`sever_names `:  表示來源頭部包含當前的`server_names `
string:任意字符串,定義服務器名或者可選的URI前綴.主機名可使用` * ` 開頭或者結尾,在檢測來源頭部這個過程當中,來源域名中的主機端口將會被忽略掉
正則表達式:`~ `表示排除https://或http://開頭的字符串.
複製代碼

看下面的配置:

valid_referers blocked server_names ~\.goole\. ~\.baidu\.;
if ($invalid_referer) {
    #return 403; // 返回403
    rewrite ^/ http://127.0.0.1:7000/403.png; // 連接到403圖片
}
複製代碼

瀏覽器緩存

優秀的緩存策略能夠提升網頁的反應速度,能夠縮短網頁請求的距離,減小延遲,緩存文件能夠重複利用,能夠減小帶寬,下降網絡負荷,提升用戶體驗。

簡單說一下都有哪些緩存

強緩存:Expires,Cache-Control

協商緩存:Etag,Last-Modified

強緩存指的是瀏覽器不用發出請求,直接命中緩存的狀況,返回200(from disk cache)。協商緩存指的是瀏覽器發出請求,可是通過服務器驗證能夠直接使用客戶端的緩存,返回狀態碼304,這兩種其實都是表明客戶端的緩存沒有過時,若是過時就直接去請求最新的資源,返回狀態碼200。

咱們能夠在nginx裏去配置相關的強緩存,對於協商緩存,在相對高的nginx版本里面,會自動給客戶端返回Last-Modified跟Etag。客戶端在下次請求一樣的url,根據HTTP協議的規定,會帶上If-Modified-Since報頭,值爲上次服務器返回的Last-Modified值,詢問服務器是否被修改過;同時也會帶一個If-None-Match報頭,值爲上次服務器返回的Etag值。 咱們能夠在Response Headers 跟 Request Headers 中查看這些參數。

強緩存配置:

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    expires 1d;#s,m,h,d
    root /usr/local/test-img; 
}
複製代碼

對於常常改動的文件咱們有時候並不但願本身的文件應用緩存,這時候咱們能夠給nginx指定禁用一切緩存。

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    add_header Cache-Control no-store;
    root /usr/local/test-img; 
}
複製代碼

說下no-cache跟no-store的區別:

請求頭中的no-cache表明每次都去請求新的資源,跳過緩存。

響應頭中的no-cache表明每次都要去服務器驗證緩存是否過時。

no-store 表明禁用一切緩存。

另外請求頭中的cache-control:max-age=0表明每次都要去服務器驗證緩存是否過時。

之後有時間再具體講一下瀏覽器緩存這部分的內容吧~

代理服務器

前提:本次是在一臺服務器上作驗證,用不一樣的端口來模擬不一樣服務器之間的交互。

代理分爲正向代理跟反向代理;

  • 正向代理是爲客戶端作代理,代替客戶端去訪問服務器;
  • 反向代理是爲服務器作代理,代替服務器接受客戶端請求。

前端經常使用的代理是反向代理,下面講解下反向代理:

反向代理是指以代理服務器來接受網絡上的鏈接請求,而後將請求轉發給內部網絡上的服務器,把數據返回給客戶端,此時代理服務器對外就表現爲一個源服務器。

nginx 反向代理的指令不須要新增額外的模塊,默認自帶proxy_pass指令,只須要修改配置文件就能夠實現反向代理。

location / { 
    // 處理跨域請求
    add_header Access-Control-Allow-Origin *;
    // 請求頭支持的傳遞字段
    add_header Access-Control-Allow-Headers "Origin, Content-Type";
    //涉及預檢請求,服務器須要容許該方法
    add_header  Access-Control-Allow-Methods "OPTIONS";
    // 代理網路請求到本地3000端口
    proxy_pass http://localhost:3000; 
    // 重寫主機名,防止後端真實的服務器設置有相似防盜鏈或者根據http請求頭中的host字段來進行路由或判斷功能
    proxy_set_header Host  $host;
    // 重寫服務器ip ,防止後端有防攻擊策略的話,機器會被封掉
    proxy_set_header X-Forwarded-For  $remote_addr
    // 請求端真實的IP
    proxy_add_x_forwarded_for: client ;
 }
複製代碼

負載均衡

負載均衡的做用:實如今不一樣地域的服務器間的流量調配,保證使用最佳的服務器服務離本身最近的客戶,從而確保訪問質量

在http層面下添加upstream節點:

upstream clusters {
    server 127.0.0.1:9001;
    server 127.0.0.1:9002;
    server 127.0.0.1:9003;
    server 127.0.0.1:9004;
}
複製代碼

本地添加靜態資源服務做爲被請求服務器,請求服務器配置:

server {
    listen       9005;
    server_name  localhost;
    location / {
        proxy_pass http://clusters;
    }
 }
複製代碼

curl http://localhost:9005或者在瀏覽器請求去驗證負載均衡是否起做用。

能夠看到每次的請求都被均勻的分配到不一樣的服務器

Upstream能夠爲每一個服務單獨設置狀態值

down:表示當前server暫時不參與負載
backup: 預留的備份服務器,壓力最小
max_fails:容許請求失敗的次數
fail_timeout : 通過max_fails失敗後,服務暫停的時間
max_conns:限制最大的接收的鏈接數
複製代碼

每一個服務的調度算法講解

輪詢:按時間順序逐一分配到不一樣的後端服務器
weight:默認爲1 weight越大,匹配的機會越多
upstream clusters {
    server 127.0.0.1:9001;// 訪問比率:20%
    server 127.0.0.1:9002; //訪問比率: 20%
    server 127.0.0.1:9003 weight=2;//訪問比率:40%
    server 127.0.0.1:9004 weight=1; //訪問比率:20%
}

ip_hash:每一個請求按訪問ip的hash結果分配,這樣來自同一個ip的固定訪問一個後端服務器,能夠解決服務端的用戶session問題 
upstream clusters {
    ip_hash;
    server 127.0.0.1:9001;
    server 127.0.0.1:9002; 
    server 127.0.0.1:9003;
    server 127.0.0.1:9004;
}
url_hash:按照訪問的url的hash結果來分配請求,是每一個url定向到同一個後端服務器,能夠解決緩存失效問題
upstream clusters {
    //$request_uri是nginx內部拋出的變量,指的是除了域名的部分
    hash $request_uri;
    server 127.0.0.1:9001;
    server 127.0.0.1:9002; 
    server 127.0.0.1:9003;
    server 127.0.0.1:9004;
}
least_conn :最少連接數,那個機器鏈接數少就分發
複製代碼

curl http://localhost:9005或者在瀏覽器請求去驗證這些參數的做用。

location部分

1.書寫匹配location規則的時候會有一些糾結加不加/的問題,下面討論下匹配url加/與不加/的區別;轉發請求路徑(也就是proxy_pass後面路徑)加/與不加/的區別。

匹配url加不加/的區別

預先在127.0.0.1:9006機器上定義好了靜態資源:

/usr/local/test-html/taobao/taobao.html
/usr/local/test-html/taobaowang/taobao.html
複製代碼

咱們先定義請求路徑(本地資源):

http://localhost:9007/taobao/taobao.html,
http://localhost:9007/taobaowang/taobao.html
複製代碼

先看下面加/的配置:

location /taobao/ {
    proxy_pass http://127.0.0.1:9006; 
}
複製代碼

分別請求上面兩個路徑(可在瀏覽器端也能夠用下面的命令):

curl http://localhost:9007/taobao/taobao.html

curl http://localhost:9007/taobaowang/taobao.html

再來看一下不加/的配置:

location /taobao {
    proxy_pass http://127.0.0.1:9006; 
}
複製代碼

分別請求上面兩個路徑(可在瀏覽器端也能夠用下面的命令):

curl http://localhost:9007/taobao/taobao.html

curl http://localhost:9007/taobaowang/taobao.html

經過比較:加/只能匹配到/usr/local/test-html/taobao/taobao.html資源;而/usr/local/test-html/taobaowang/taobao.html資源匹配不到;不加/兩個資源都能獲得。

能夠得出結論:因爲location進行的是模糊匹配,因此對於加/的這種狀況只能匹配像/taobao/any這種url,不加/的狀況能夠匹配/taobao[any]這種url

轉發的請求路徑加不加/的區別

預先在127.0.0.1:9006機器上定義好了靜態資源:

/usrl/local/test-html/taobao/forward.html
/usrl/local/test-html/forward.html
複製代碼

咱們先定義請求路徑爲:http://localhost:9007/taobao/forward.html

先看下面加/的配置:

location /taobao/ {
    proxy_pass http://127.0.0.1:9006/; 
}
複製代碼

請求定義路徑(可在瀏覽器端也能夠用下面的命令):

curl http://localhost:9007/taobao/forward.html

再來看下不加/的配置:

location /taobao/ {
    proxy_pass http://127.0.0.1:9006; 
}
複製代碼

請求定義路徑(可在瀏覽器端也能夠用下面的命令):

curl http://localhost:9007/taobao/forward.html

經過比較:加/訪問的資源是/usrl/local/test-html/forward.html, **不加/**訪問的資源是/usrl/local/test-html/taobao/forward.html

能夠得出結論:加/的話至關於絕對路徑,不會把location中匹配的url代理走,不加/的話會把匹配的路徑部分也給代理走

2.實際項目中每一個虛擬主機中會有多個location配置,那這樣就會涉及到匹配location的順序問題

location  [=|~|~*|^~|@ ]  /url/  {config}
= 表示精確匹配
~ 表示正則匹配,區分大小寫
~*表示正則匹配 ,不區分大小寫
^~表示不匹配正則
@表示internally redirected (內部重定向,表示forward)
首先分類下:分爲普通的location跟正則lcoation
正則location: `~ |~*
通常location:`= | ^~|@
複製代碼

驗證匹配優先級

1.兩個普通的location配置

location /taobao/ {
    root /usr/local/test-html;
    allow all;
}
location /taobao/taobao.html {
    root /usr/local/test-html;
    deny all;
}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

如今把下面的location註釋:

location /taobao/ {
    root /usr/local/test-html;
    allow all;
}
#location /taobao/taobao.html {
    #root /usr/local/test-html;
    #deny all;
#}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

結論:普通location之間的順序規則是有個最大匹配原則,越精確優先級越高

2.正則location配置

location ~ \.html$ {
    root /usr/local/test-html;
    allow all;
}
location ~ /taobao.html {
    root /usr/local/test-html;
    deny all;
}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

如今把兩個配置換個位置:

location ~ /taobao.html {
    root /usr/local/test-html;
    deny all;
}
location ~ \.html$ {
    root /usr/local/test-html;
    allow all;
}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

結論:正則location之間會有順序,寫在前面的會被優先匹配到

3.優先級高的普通location跟正則location配置

location  /taobao/taobao.html {
    root /usr/local/test-html;
    deny all;
}
location ~ \.html$ {
    root /usr/local/test-html;
    allow all;
}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

結論:正則location優先級要高於普通的lcoation

4.精確location跟正則location的配置

location = /taobao/taobao.html {
    root /usr/local/test-html;
    deny all;
}
location ~ \.html$ {
    root /usr/local/test-html;
    allow all;
}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

結論:精確location優先級要高於正則location

5.特殊狀況^~ location跟正則location還有普通location的配置

location /taobao/taobao.html {
    root /usr/local/test-html;
    deny all;
}
location ^~ /taobao/ {
    root /usr/local/test-html;
    deny all;
}
location ~ \.html$ {
    root /usr/local/test-html;
    allow all;
}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

能夠看到起做用的是最後一個配置,好像`^~ `沒有起做用

咱們把配置改變一下:

#location /taobao/taobao.html {
    #root /usr/local/test-html;
    #deny all;
#}
location ^~ /taobao/ {
    root /usr/local/test-html;
    deny all;
}
location ~ \.html$ {
    root /usr/local/test-html;
    allow all;
}
複製代碼

註釋第一個配置,執行curl http://localhost:9008/taobao/taobao.html,獲得:

能夠看到第二個配置已經起做用`^~ `,表明不匹配正則表達式

那爲何如今起做用呢?根據上面的配置咱們把普通location中的優先級高的配置註釋掉了。那是否是這個優先級高的配置把^~的配置覆蓋掉了呢?

咱們如今再把配置改變一下:

location ^~ /taobao/taobao.html {
    root /usr/local/test-html;
    deny all;
}
location  /taobao/ {
    root /usr/local/test-html;
    deny all;
}
location ~ \.html$ {
    root /usr/local/test-html;
    allow all;
}
複製代碼

執行curl http://localhost:9008/taobao/taobao.html,獲得:

如今能夠看到這個普通lcoation優先級高的配置把`^~ `覆蓋掉了,因此這個`^~ `也屬於普通lcoation。

結論:^~屬於普通的lcoation,遵循普通location的規則,若是被覆蓋,後面還有正則location的話,則正則location優先級更高

整體結論:精確匹配 (=) > 正則lcoation(有順序限制,只匹配第一個) > 普通lcoation (最大匹配原則),這裏有個特殊狀況是遇到^~,在不被覆蓋的狀況下,不匹配後面的正則location。

rewrite模塊

先說下rewrite的指令:

break:中止執行該模塊的指令集
if:根據條件決定是否執行語句
return: 返回一個狀態值給客戶端
rewrite: 根據表達式來更改url
set:能夠設置一個變量
複製代碼

if指令

syntax: if (condition);
default:-
context:server, location,if
複製代碼

驗證條件邏輯:

表達式只是一個變量時,值爲""或任何以0開頭的字符串都會當作false
直接時使用=或!=,跟js有區別
正則表達式匹配,~區分大小寫,~*不區分大小寫的匹配,!~,!~表示不匹配
-f和!-f用來檢測一個文件是否存在
-d和!-d用來檢測一個目錄是否存在
-e和!-e用來檢測是否存在一個文件,一個目錄或者一個符號連接
-x和!-x用來檢測一個文件是否可執行
複製代碼

舉個例子:(見如下配置)

if ($http_user_agent ~ Safari) {
    return 401;
}
複製代碼

在瀏覽器訪問http://localhost:9009/,獲得:

rewrite指令

syntax: rewrite regex replacement [flag];
default:-
context:server, location,if

regex:正則表達式
replacement: 新的url
flag:包含這幾個值:last, break, redirect, permanent
	last:中止處理rewrite模塊的指令集,並根據replacement繼續匹配location
	break:中止處理rewrite模塊的指令集
	redirect:返回302臨時重定向
	permanent:返回301永久重定向
複製代碼

last跟break的區別

配置:

location / {
    rewrite ^/code/ /test last;
    return 403;
}
location /test {
    return 500;
}
複製代碼

執行curl http://localhost:9009/code/*獲得:

如今更改下配置:

location / {
    rewrite ^/code/ /test break;
    return 403;
}
location /test {
    return 500;
}
複製代碼

執行curl http://localhost:9009/code/*獲得:

再更改下配置:

location / {
    rewrite ^/code/ /test;
    return 403;
}
location /test {
    return 500;
}
複製代碼

執行curl http://localhost:9009/code/*獲得:

結論:last跟break都能中止rewrite模塊的指令集,可是last會繼續匹配location,break就地終止。

另外說下請求參數的問題

下面看個例子:

location / {
    rewrite /code /testparams permanent;
}
複製代碼

瀏覽器請求:http://localhost:9009/code?a=1將會看到瀏覽器地址被重定向到 http://localhost:9009/testparams?a=1,舊參數被添加到新的url上了

咱們下面來改一下配置:

location / {
    rewrite /code /testparams? permanent;
}
複製代碼

瀏覽器請求:http://localhost:9009/code?a=1將會看到瀏覽器地址被重定向到 http://localhost:9009/testparams,舊參數被省略掉了

結論:默認狀況下舊的url請求的參數會放在新替換的url 後面,若是想省略舊的請求參數在新的url後面加上?就行了。

好了目前先寫到這吧,感受不錯的話留下你的👍~

Nginx中文網地址:www.nginx.cn/doc/index.h…

相關文章
相關標籤/搜索