第一次使用nginx反向代理的大坑

項目需求:

經過webpack-dev-server中間件代理訪問配置在nginx上的反向代理服務端口,從而實現跨域請求資源。php

最終實現

webpack配置html

devServer: {
    host: 'localhost',
    port: 8000,
    proxy: {  // 代理配置
      '/v1':{
        target: "http://localhost:8001", // 代理服務器地址,nginx會監聽此接口下的請求,並代理請求真正的網址
        pathRewrite: {'^/v1' : ''}
      }
    }
  }

nginx配置webpack

resolver 8.8.8.8; #配置域名進行訪問的時候,須要配置此項目,不然會報502錯誤
server {
   listen       8001; #代理服務器端口
   server_name  localhost; #域名
   location / { #路由規則 代理全部請求到https://u.y.qq.com/cgi-bin/musicu.fcg
       proxy_pass  https://u.y.qq.com/cgi-bin/musicu.fcg?$query_string;
       }
 }

實現過程當中的各類坑

爲了本身之後不在這種地方犯迷糊,也但願能給你們一些幫助,因此總結一下我遇到的各類坑nginx

1. 如何保證webpack代理到正確的路徑

首先咱們要清除webpack-dev-server的轉發機制,就以我上面代碼中的設置web

host: 'localhost',
port: 8000,
proxy: {  // 代理配置
      '/v1':{
        target: "http://localhost:8001", 
      }

這個代理的結果就是跨域

訪問http://localhost:8000/v1 → 代理監聽到這個請求 → 轉發到http://localhost:8001/v1服務器

能夠看到這層代理只是更改了域名http://localhost:8000部分後面的路徑徹底照搬,因此在nginx的代理規則中咱們必定要清楚的認識到從webpack-dev-server轉發過來地url是怎麼樣的。cookie

另一定要注意的是,這個監聽的是以/v1開頭的全部url,無論你是/v1aa仍是/v1/aa,只要是以/v1開始就行,webpack-dev-server

不要使用正則,例如/v1/*,這個匹配的是以 /v1/*xxx而不是/v1/xxx都是血淚教訓,編碼

另外我還不清楚這個配置可否使用正則,知道的朋友能夠告訴我一下.

若是要取消後面的部分路徑怎麼辦呢

proxy: {  // 代理配置
      '/v1':{
        target: "http://localhost:8001", 
        pathRewrite: {'^/v1' : ''}
      }

經過pathRewrite: {'^/v1' : ''}路徑重寫方法,將路徑中的部份內容重寫爲想要的內容,具體使用方法請自行百度。

2. 如何保證nginx正確轉發

如今咱們知道了,向nginx服務器發起的請求地址爲http://localhost:8001/v1,如今就能夠在nginx配置中着手處理請求了。

resolver 8.8.8.8; #配置域名進行訪問的時候,須要配置此項目,不然會報502錯誤
server {
   listen       8001; #由於請求的是8001端口,因此咱們監聽這個端口
   server_name  localhost; #域名的做用同端口
   location / { #路由規則 代理全部請求到https://u.y.qq.com/cgi-bin/musicu.fcg
       proxy_pass  https://u.y.qq.com/cgi-bin/musicu.fcg?$query_string;
       }
 }

整個匹配機制的關鍵就在於

location / { 
       proxy_pass  https://u.y.qq.com/cgi-bin/musicu.fcg?$query_string;    
}

這個部分中的location的意思就是url中除去域名的部分,以http://localhost:8001/v1爲例

location就是/v1

location / 中的/就是匹配的關鍵,具體見下

= 開頭表示精確匹配

^~ 開頭表示url以某個常規字符串開頭,理解爲匹配url路徑便可,nginx不對url作編碼,所以請求爲/static/20%/aa,能夠被規則 ^$ /static/ /aa 匹配到

~ 區分大小寫的正則匹配

~* 不區分大小寫的正則匹配

!~ !~* 區分大小寫不匹配及不區分大小寫不匹配的正則

/ 通用匹配,任何請求都會匹配到

同時這個匹配機制是由順序的,順序爲

多個location配置的狀況下匹配順序

爲首先匹配 =

其次匹配 ^~

其次是按文件中的順序的正則匹配,

最後是交給 / 通用匹配。

當匹配成功的時候,中止匹配,按當前匹配規則處理請求。

由於個人當前項目暫時沒有其餘轉發需求,因此我配置的全部請求都轉發到同一個地址.

3. nginx一些內置參數的含義

$args : #這個變量等於請求行中的參數,同$query_string
$content_length : 請求頭中的Content-length字段。
$content_type : 請求頭中的Content-Type字段。
$document_root : 當前請求在root指令中指定的值。
$host : 請求主機頭字段,不然爲服務器名稱。
$http_user_agent : 客戶端agent信息
$http_cookie : 客戶端cookie信息
$limit_rate : 這個變量能夠限制鏈接速率。
$status  請求狀態
$body_bytes_sent 發送字節
$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相同。

其中$args$query_string的內容是同樣的,都是url中的參數字符串.假設一個url爲http://localhost:8000/v1/?a=1&b=2&c=3

$args的值爲a=1&b=2&c=3

這裏須要注意這個部分是不帶?的因此在轉發拼接參數的時候必定要帶上?

例如:proxy_pass https://u.y.qq.com/cgi-bin/musicu.fcg?$query_string;

最後:但願之後我不在爲這個問題苦惱你們也同樣.最後祝你們編碼愉快,頭髮茂盛。
相關文章
相關標籤/搜索