為什麼前端需要配置API代理?
我們在開發一個專案的時候,如果服務採用的是分散式部署,也就是說按不同模組或功能部署於不同的伺服器,如下圖
客戶端不同的請求會被主伺服器轉發到對應的伺服器上去,如果在開發階段,也有一個這樣做轉發的伺服器,那麼前端的開發是不需要配置代理的,我們今天要探討的是開發階段無轉發伺服器,需要前端配置代理的情況,如下圖 大家都知道,瀏覽器是存在跨域限制的,處於安全性考慮,伺服器ABC不可能設定為允許任何請求都可以訪問,So, 我們配置前端API的代理的目的其實就是為了解決跨域問題,前端按照既定的規則配置好代理之後,就能保證開發階段和線上部署服務的一致。配置前端API代理的三種方式
本文以配置Dva專案的代理為示例,因為Dva專案的腳手架自帶Mock功能,省去了自己寫介面的麻煩,同時公司內部專案也採用此技術,能讓團隊人員也做一參考。
拉取程式碼,安裝依賴之後,訪問http://localhost:8000(預設是8000埠,如果被佔用,會在其他埠),就能看到Welcome to dva的歡迎頁面。專案中.roadhogrc.mock.js為Mock資料的配置檔案,現為
在瀏覽器中輸入 http://localhost:8000/users/1 就能看到返回的是你在.roadhogrc.mock.js中配置的資料 我們最終要達成的目的:- 使用www.frontproxy.com訪問開發環境,即在瀏覽器輸入www.frontproxy.com等同於輸入localhost:8000。
- 將users、todos、posts模組也就是請求路徑中以/users/、/todos/、/posts/開始的請求介面,都代理到不同的伺服器。
- 最終實現請求如 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
現在我們訪問www.frontproxy.com:8000和訪問localhost:8000的效果是一樣的,
因為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 頁面並沒有自動重新整理,手動重新整理後修改的內容才顯示出來,並且頁面中有一個報錯
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中新增如下配置,對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 返回的資料,說明代理已經生效
同理對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預設的埠,如果你更改過,請填寫你更改後的埠
配置生效以後檢視Chrome瀏覽器中代理的設定, 此時,通過Chrome瀏覽器發出的請求,就會被Charles抓住 現在我們開始配置Charles的代理規則,如下圖開啟Charles中tools中的Map Remote點選add按鈕進行新增
如圖將 www.frontendproxy.com 代理到 127.0.0.1:8000上,配置好之後,訪問域名和訪問IP效果是一樣的,如果上文配置好Hosts和Nginx之後的效果,同樣需要配置/sockjs-node/的代理,這樣更改檔案後可以自動儲存了,下面新增users模組的代理 Charles代理規則的優先順序是從上到下的,也就是說上面的規則會覆蓋下面的規則,這點需要注意下 OK,到這裡Charles代理前端API請求的配置就已經完成了。Wepack + Host Switch Plus配置
現在前端開發環境中基本上都有用到webpack,其中webpack-dev-server這個包也是使用webpack搭建開發環境所必備的,我們常用的自動重新整理和熱更新功能就是由它提供的,今天所要講的proxy功能也是如此。
Host Switch Plus,顧名思義就是對host的管理工具,它是一個Chrome的外掛,需要你在Chrome應用商店下載。
首先我們先配置對域名的代理,支援單個新增和批量新增
新增完成之後,我們點選外掛的圖示就能看到你剛才配置的資訊,Enable為勾選,IP前面的圓點為綠色表示已生效 此時,訪問 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"
}
},
}
}
複製程式碼
總結
下面是劃重點時間,我們從適用範圍、配置難易、團隊協作成本三個方面對比一下這三種配置方式
國慶節的一天就這麼過去了,覺得有幫助的童鞋,幫忙點個?喲!