最近同事小G老是悶悶不樂,讓我感受慌慌的,難道是我平時壓榨小G了?我轉念一想,不該該啊,工做量事先都評估好了,沒道理每天加班啊。html
坐下來聊聊後,小G向我吐槽說,」改bug效率過低了,天天加班改bug,都不能早點下班陪女神!」前端
我深吸一口氣,「臥槽,忘記傳授小G祕籍了...」linux
在一步步提問引導下,我搞清楚了小G的問題所在......webpack
相信不少前端朋友在線上debug時都吐槽過npm run dev
或npm start
太費時的問題吧(這裏提到的兩條npm腳本代指啓動前端dev server)。nginx
因爲環境差別,開發環境和生產環境下,咱們訪問的後端服務域名是不同的。那麼當咱們debug生產問題時,不免仍是要修改下webpack devServer
的proxy
配置指向生產環境域名,而後重啓devServer
,這個過程通常比較緩慢。web
有些時候可能測試環境也能復現bug,那麼只要接入測試環境也能排查問題緣由。但這不是本文關注的重點,本文主要說說如何提升debug效率。npm
0202年了,若是做爲開發者的你還不瞭解反向代理,那麼是頗有必要去關注下了。windows
咱們知道,跨域對於前端而言是一個沒法逃避的問題。若是不想在開發時麻煩後端同事,前端仔必須經過本身的手段解決跨域問題。固然,你幫後端同事買包辣條,他給你經過CORS解決跨域也是能夠的。後端
還好,webpack-dev-server
幫咱們解決了這個痛點,它基於Node代理中間件http-proxy-middleware
實現。api
配置起來也很是簡單:
proxy: {
// 須要代理的url規則 "/api": { target: "https://dev.xxx.tech", // 反向代理的目標服務 changeOrigin: true, // 開啓後會虛擬一個請求頭Origin pathRewrite: { "^/api": "" // 重寫url,通常都用獲得 } } } 複製代碼
這個時候小G打斷了我,表示不理解。
反向代理是個什麼意思呢?舉個例子,我想找馬雲借錢,馬雲是確定不會借給個人。
可是我有一個好朋友老張,我因而找老張借了1W塊,可是我沒想到這個朋友和馬雲關係不錯,他從馬雲那裏借了1W塊,而後轉給我。也就是說,我不知道我借到的錢實際來源於哪裏,我只知道我從我朋友老張那裏借到了錢,老張給我作了一層反向代理。
具體到開發中就是,我前端仔要從https://dev.xxx.tech
這個域名調用後端接口,可是我前端開發服務運行在http://localhost:8080
,直接調用後端接口會跨域,被瀏覽器同源策略阻塞,因此這條路是走不通的。
所以我須要從前端服務器作個代理,這樣我就能夠用http://localhost:8080/api/user/login
這種形式調用接口,就好像在調前端本身的接口同樣(由於我訪問的是前端的url嘛)。
然而其實是前端服務器作了一層代理,把http://localhost:8080/api/user/login
這個接口代理到https://dev.xxx.tech/user/login
。這對前端開發者而言是無感的。
簡單總結就是:反向代理隱藏了真實的服務端;相反地,正向代理隱藏了真實的客戶端,相似kexueshangwang這種。
問題來了,假設咱們正在feature
分支開發需求,這個時候上頭通知要即時排查和解決一個生產bug,假設生產環境域名爲https://production.xxx.tech
。
咱們通常會stash
代碼,而後切fix
分支,修改target
的值爲"https://production.xxx.tech"
,而後從新運行npm start
重啓開發服務器接入生產環境,靜靜等待,放空本身......
這個時候咱們就會幻想「唉,要是不用等這麼久就行了!」
是的,其實不少時候,一個bug並不複雜,可能解決bug只要1分鐘,然而咱們切換環境從新運行開發服務器就花了1分鐘(大多數狀況可能超過這個時間)。那麼如何解決這個問題?
是的,有的同窗已經想到了,只要把代理服務器抽離出來,問題即可以獲得解決,我再也不須要把前端編譯過程和服務代理目標捆綁在一塊兒。在生產環境,這種Nginx轉發對大多數人而言早已經是熟門熟路,然而不多有人會嘗試在開發環境中也這麼作。那麼不妨這樣試試呢!
咱們照常下載Nginx,選擇Windows穩定版便可。
爲了不在debug線上問題時須要切換proxy target而從新運行npm start
,咱們在前端層把proxy target固定下來。好比我固定訪問127.0.0.1:8090
(固然,實際上訪問哪一個端口能夠視我的狀況調整)。
proxy: {
"/api": { target: "127.0.0.1:8090", // 固定代理目標 changeOrigin: true, pathRewrite: { "^/api": "" } } } 複製代碼
而後從127.0.0.1:8090
確定是沒法訪問到後端接口的,請接着往下看!
因爲前端的接口訪問已經固定爲127.0.0.1:8090
,那麼剩下的工做就交給Nginx吧。咱們只要在Nginx中監聽本地8090端口,把請求通通轉發給目標服務器便可,配置以下:
server {
listen 8090; server_name 127.0.0.1; location / { proxy_pass https://dev.xxx.tech; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } 複製代碼
能夠看到,我在配置中註釋了X-Real-IP,而咱們在生產環境下配置Nginx時,通常會保留這幾項Host,X-Real-IP,X-Forwarded-For,用以保留請求的服務器域名,原始客戶端和代理服務器的IP等信息。
若是不註釋X-Real-IP,前端訪問入口的真實IP是127.0.0.1
或localhost
,Nginx不承認這樣的本地ip,直接返回404,客戶端請求不予代理到其餘遠程服務器。不扯了,這裏具體的緣由我也不知,若有大佬知道緣由,還請點撥下,太感謝了。
好了,回到正題,有了以上的配置,咱們就能夠將前端代理層和Nginx代理層解耦,前端固定經過本地127.0.0.1:8090
訪問後端接口,而具體接口是代理到開發環境、測試環境或是生產環境,由Nginx決定,只須要修改nginx.conf
後重啓便可。
而Nginx熱重啓是很是快的,一條命令便可實現,幾乎零等待時間。
// windows下是這個命令 nginx.exe -s reload // linux是這樣的 nginx -s reload 複製代碼
聽到這裏,小G又將了我一軍。
還好我早有準備,沒有自亂陣腳。
若是真的遇到本地端口被佔用的狀況,最簡單的辦法固然是換個端口。
爲了杜絕這種狀況,咱們能夠引入本地域名,兼具「裝逼」效果。
咱們知道,域名是經過解析後才能獲得真實的服務IP。而域名解析過程當中也有這麼一些關鍵節點,是咱們應該知道的。
借用網上一張圖說明下大體流程(侵刪)。
上圖沒提到hosts文件,可是不影響咱們魔改。咱們只要在操做系統hosts文件這個節點動下手腳,就能夠實現本地域名了。
首先,咱們找到C:\Windows\System32\drivers\etc\hosts
這個文件,打開後在最後新增一條解析記錄
127.0.0.1 www.devtest.com
複製代碼
而後保存這個文件,保存hosts文件時須要administrator權限。
這就至關於告訴本地操做系統,若是用戶訪問www.devtest.com
,我就給他解析到127.0.0.1
這個ip
因此,咱們在Nginx只要監聽127.0.0.1
的80
端口便可,配置以下。
server {
listen 80; server_name 127.0.0.1; location / { proxy_pass https://dev.xxx.tech; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } 複製代碼
最後,咱們只要在前端工程中把代理目標設置爲www.devtest.com
便可。
proxy: {
"/api": { target: "http://www.devtest.com", // 固定代理目標 changeOrigin: true, pathRewrite: { "^/api": "" } } } 複製代碼
這樣前端訪問的某接口http://localhost:8080/api/user/login
就會被代理到http://www.devtest.com/user/login
,而www.devtest.com
被本地hosts文件解析到127.0.0.1
,接着Nginx監聽了127.0.0.1
的80
端口,將請求轉發到真實的後端服務,完美!
對了,www.devtest.com
是我特地命名的一個沒法訪問的域名,因此你千萬別把www.taobao.com
這種地址解析到本地哦,否則你無法給女神買禮物別怪我。。。
今天分享給你們的乾貨就這麼多,祝願你們準點下班陪女神!
看到最後,求個關注點贊,歡迎你們加我微信交流技術,閒聊也能夠哦!
本文使用 mdnice 靈動藍主題 排版