Nginx,Charles與Webpack配置前端API代理教程(超詳細)

笑在秋風中發表於2018-10-07

為什麼前端需要配置API代理?

我們在開發一個專案的時候,如果服務採用的是分散式部署,也就是說按不同模組或功能部署於不同的伺服器,如下圖

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
客戶端不同的請求會被主伺服器轉發到對應的伺服器上去,如果在開發階段,也有一個這樣做轉發的伺服器,那麼前端的開發是不需要配置代理的,我們今天要探討的是開發階段無轉發伺服器,需要前端配置代理的情況,如下圖

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
大家都知道,瀏覽器是存在跨域限制的,處於安全性考慮,伺服器ABC不可能設定為允許任何請求都可以訪問,So, 我們配置前端API的代理的目的其實就是為了解決跨域問題,前端按照既定的規則配置好代理之後,就能保證開發階段和線上部署服務的一致。

配置前端API代理的三種方式

本文以配置Dva專案的代理為示例,因為Dva專案的腳手架自帶Mock功能,省去了自己寫介面的麻煩,同時公司內部專案也採用此技術,能讓團隊人員也做一參考。

示例地址:github.com/ranshaw/fro…

拉取程式碼,安裝依賴之後,訪問http://localhost:8000(預設是8000埠,如果被佔用,會在其他埠),就能看到Welcome to dva的歡迎頁面。專案中.roadhogrc.mock.js為Mock資料的配置檔案,現為

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
在瀏覽器中輸入 http://localhost:8000/users/1 就能看到返回的是你在.roadhogrc.mock.js中配置的資料

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
我們最終要達成的目的:

  1. 使用www.frontproxy.com訪問開發環境,即在瀏覽器輸入www.frontproxy.com等同於輸入localhost:8000。
  2. 將users、todos、posts模組也就是請求路徑中以/users/、/todos/、/posts/開始的請求介面,都代理到不同的伺服器。
  3. 最終實現請求如 www.frontproxy.com/users/1 返回的資料為請求 jsonplaceholder.typicode.com/users/1 返回的資料

注:本文中將三個模組的請求都代理到 jsonplaceholder.typicode.com 上;為了測試方便都採用Get請求,其他請求方式同Get方式;下文中講述的配置方法以Mac為例,Windows上原理一致,具體方法需自行google。

配置Nginx和Hosts實現

配置Hosts

在mac終端輸入 sudo vi /etc/hosts,對Hosts檔案進行編輯,新增如下配置 127.0.0.1 www.frontendproxy.com

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
然後儲存。如果對Vim命令不瞭解,點選Vim命令詳解學習。

現在我們訪問www.frontproxy.com:8000和訪問localhost:8000的效果是一樣的,

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
因為Hosts配置的對映關係,不支援自定義埠,所以現在訪問的時候還必須要加上埠,下面我們會通過Nginx配置,將url中埠去掉。

配置Nginx

安裝好Nginx之後,在Mac終端輸入 cd /usr/local/etc/nginx 找到nginx.conf檔案,可使用軟體開啟或者繼續輸入vi nginx.conf 新增如下配置

server {
        listen 80;
        server_name www.frontendproxy.com;
        index index.html;
        location / {
            proxy_pass http://127.0.0.1:8000/;
        }
    }
複製程式碼

在終端輸入 sudo nginx,啟動Nginx,此時在瀏覽器輸入 www.frontendproxy.com 就可以正常顯示了,但是當你修改頁面的內容你會發現,http://localhost:8000 可以自動重新整理,更新你剛才修改的內容,www.frontendproxy.com 頁面並沒有自動重新整理,手動重新整理後修改的內容才顯示出來,並且頁面中有一個報錯

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
webSocket通訊出了問題,我們需要新增如下配置

location /sockjs-node/ {
    proxy_pass http://127.0.0.1:8000/sockjs-node/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";	
 }
複製程式碼

在終端輸入sudo nginx -s reload 重啟nginx,然後發現報錯消失,修改頁面內容後,可以自動重新整理頁面了。

到這一步,我們可以使用域名訪問本地專案,進行愉快的開發了,但是請求users模組的資料仍然是Mock中的資料,

Nginx,Charles與Webpack配置前端API代理教程(超詳細)

我們在Nginx中新增如下配置,對users模組的請求進行代理,

location /users/ {
    proxy_pass http://jsonplaceholder.typicode.com/users/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
複製程式碼

在終端輸入sudo nginx -s reload重啟Nginx,再次請求 www.frontendproxy.com/users/1 你會發現返回的資料已經不是Mock配置的資料了,而是 jsonplaceholder.typicode.com/users/1 返回的資料,說明代理已經生效

Nginx,Charles與Webpack配置前端API代理教程(超詳細)

同理對todos、posts模組進行配置,完整配置如下

server {
    listen 80;
    server_name www.frontendproxy.com;
    index index.html;
    location / {
        proxy_pass http://127.0.0.1:8000/;
    }
    location /sockjs-node/ {
        proxy_pass http://127.0.0.1:8000/sockjs-node/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";	
     }
    location /users/ {
        proxy_pass http://jsonplaceholder.typicode.com/users/;
        proxy_set_header X-Real-IP $remote_addr;
	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /todos/ {
        proxy_pass http://jsonplaceholder.typicode.com/todos/;
        proxy_set_header X-Real-IP $remote_addr;
	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /posts/ {
        proxy_pass http://jsonplaceholder.typicode.com/posts/;
        proxy_set_header X-Real-IP $remote_addr;
	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
複製程式碼

OK,我們現在已經完成了對users、todos、posts模組請求介面的代理,不同模組對應的伺服器的地址,都可以自定義設定。

Charles配置代理

Charles為Mac上一個超級好用的抓包軟體,特別是對於移動端開發介面的除錯,簡直不要太爽,在此不做延伸,後續會專門寫文章介紹,下載地址為: 連結: pan.baidu.com/s/1UCJu9KaB… 提取碼: shfp。

如果你按照上文教程配置了Hosts和Nginx,請把相關配置都清除掉,然後我們開始Charles的配置。

Charles並不能直接對Chrome進行抓包,需要對Chrome設定代理, 我這使用的是Chrome的一個外掛SwitchyOmega,在SwitchOmega中配置代理,8888為Charles預設的埠,如果你更改過,請填寫你更改後的埠

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
配置生效以後檢視Chrome瀏覽器中代理的設定,

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
此時,通過Chrome瀏覽器發出的請求,就會被Charles抓住

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
現在我們開始配置Charles的代理規則,如下圖開啟Charles中tools中的Map Remote

Nginx,Charles與Webpack配置前端API代理教程(超詳細)

點選add按鈕進行新增

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
如圖將 www.frontendproxy.com 代理到 127.0.0.1:8000上,配置好之後,訪問域名和訪問IP效果是一樣的,如果上文配置好Hosts和Nginx之後的效果,同樣需要配置/sockjs-node/的代理,這樣更改檔案後可以自動儲存了,下面新增users模組的代理

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
Charles代理規則的優先順序是從上到下的,也就是說上面的規則會覆蓋下面的規則,這點需要注意下

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
OK,到這裡Charles代理前端API請求的配置就已經完成了。

Wepack + Host Switch Plus配置

現在前端開發環境中基本上都有用到webpack,其中webpack-dev-server這個包也是使用webpack搭建開發環境所必備的,我們常用的自動重新整理和熱更新功能就是由它提供的,今天所要講的proxy功能也是如此。

Host Switch Plus,顧名思義就是對host的管理工具,它是一個Chrome的外掛,需要你在Chrome應用商店下載。

首先我們先配置對域名的代理,支援單個新增和批量新增

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
新增完成之後,我們點選外掛的圖示就能看到你剛才配置的資訊,Enable為勾選,IP前面的圓點為綠色表示已生效

Nginx,Charles與Webpack配置前端API代理教程(超詳細)
此時,訪問 www.frontendproxy.com已經代理到 http://localhost:8000 上,我們再開啟專案中的 .webpackrc 檔案,新增如下配置

{
  "proxy": {
  "/sockjs-node/": {
    "target": "http://127.0.0.1:8000/",
    "changeOrigin": true
  },
  "/users/": {
    "target": "http://jsonplaceholder.typicode.com/",
    "changeOrigin": true
  },
  "/todos/": {
    "target": "http://jsonplaceholder.typicode.com/",
    "changeOrigin": true
  }
}
}
複製程式碼

好了,關於webpack配置代理的操作,到這裡也完成了,關於webpack-dev-server中proxy配置的詳細規則,請點選檢視,我這裡不再一一講述。

注意: 如果你現在使用的是Nginx配置的代理,現在想轉為webpack配置代理,假如要代理的模組為/users/,期望代理的介面地址為http://localhost:8000/login,Nginx和Webpack的配置分別如下,最終代理伺服器發出的請求為http://jsonplaceholder.typicode.com/login,Webpack的配置項要多加一項配置pathRewrite,對代理伺服器的路徑進行重寫,將請求中的/users/替換為/,有時候後端會需要請求頭中的某些值,這時候就需要新增自定義請求頭(版本webpack-dev-server@3.1.7),如下:

 Nginx配置:
 location /users/ {
        proxy_pass http://jsonplaceholder.typicode.com/;
        proxy_set_header X-Real-IP $remote_addr;
	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
 Webpack配置:
 {
  "proxy": {
  "/users/": {
    "target": "http://jsonplaceholder.typicode.com/",
    "changeOrigin": true"pathRewrite": { "^/users/": "/" },
    "headers":{
       // 你需要定義的請求頭
       Host: "localhost:8000"
    }
  },
}
}
複製程式碼

總結

下面是劃重點時間,我們從適用範圍、配置難易、團隊協作成本三個方面對比一下這三種配置方式

Nginx,Charles與Webpack配置前端API代理教程(超詳細)

國慶節的一天就這麼過去了,覺得有幫助的童鞋,幫忙點個?喲!

相關文章