在《Vue CLI4.0 webpack設定屬性——devServer》中,我初略提及了 devServer.proxy 。但是並沒有做詳細的講解。一、是因為,面對跨域問題,我常用的做法是讓後端做處理;第二個原因呢?其實我並沒有真正的設定成功過。所以我不敢寫,怕誤導大家。
關於後端如何處理跨域問題,可檢視:《koa2 + VueCLI 4.0 + axios 跨域問題》
devServer.proxy
Type: object
[object, function]
作用: 設定API存取代理。如果你有單獨的後端開發伺服器 API,並且希望在同域名下傳送 API 請求 ,那麼代理某些 URL 會很有用。
用法
module.exports = {
proxy: {
'/api': {
target: 'http://127.0.0.10:3000'
}
}
};
targe
Type: string
作用:代理的伺服器,也就是api要存取的伺服器。
用法:
module.exports = {
proxy: {
'/api': {
target: 'http://127.0.0.10:3000'
}
}
};
ws
Type: boolean
作用:是否代理websocket
用法:
module.exports = {
proxy: {
'/api': {
target: 'http://127.0.0.10:3000',
ws: true
}
}
};
secure
Type: boolean
作用:是否使用HTTPS協定。預設,false。
用法:
module.exports = {
proxy: {
'/api': {
target: 'http://127.0.0.10:3000',
secure: true
}
}
};
changeOrigin
Type: boolean
作用: 將主機頭的來源更改為目標URL,也就是是否允許跨域
用法:
module.exports = {
proxy: {
'/api': {
target: 'http://127.0.0.10:3000',
changeOrigin: true
}
}
};
pathRewrite
Type: object
作用:重寫 url 的 path 部分。
用法:
module.exports = {
proxy: {
'/api': {
target: 'http://127.0.0.10:3000',
pathRewrite: {"^/api" : ""}
}
}
};
path
是什麼?假設我們有這樣一個url: https://github.com/chimurai/http-proxy-middleware
那path
是上面那一部分呢?
首先,我要明確一點。這裡的path
不等於url
,它是url
中的一部分。這可能是很多人理解錯的地方。
請看下圖:
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
這是《http-proxy-middleware》官方檔案給出來的圖。上面標示了一個url
的結構。、
各個部分說明如下:
類比快遞:
scheme 就是派送的快遞;authority + path 則組成快遞地址,authority 是個大致地址,就好比快遞地址的城市,而 path 就是地址中城市後面的詳細地址了;query就是快遞本身;而fragment則是快遞單的備註或者是快遞的說明書。
當然了,上面的比喻可能不恰當啦!
關於這部分的更詳細的講解,可檢視:《URI’s fragment》
proxy 接受一個物件,物件鍵值對的 key 用來匹配 api 的 url 中的 path。也就是說,當我們進行如下設定時:
module.exports = {
proxy: {
'/api': {
target: 'http://127.0.0.10:3000',
}
}
};
devServer 會自動對 path 為 /api
開頭的 api 做代理轉發。而 path 不是 /api
開頭的就不會進行處理。
注意:
需要注意一點,devServer 預設傳遞過來的 api url 是不包含 scheme 和 authority 的。換而言之,devServer 會從傳遞過來的 api url 的第一個字元進行匹配。如果你給api url 補上了 scheme 和 authority 的(如:
http://127.0.0.10:3000/api/getData
),它是不匹配的,因為開頭是http
。所以如果我們需要使用 devServer.proxy 。那就一定不能設定 axios 的 baseURL,或者把baseURL設為空字串
pathRewrite 接受一個物件。
key: 物件鍵值對中的 key 是一個正規表示式。這裡需要注意正則的寫法,必須與^
開頭。熟悉正規表示式的朋友就會知道,這表明,傳給 deveServer.proxy 的 api 的 url 必須是以正規表示式所要匹配的字串開頭。
例如:
我們做了如下設定
pathRewrite: {"^/api" : ""}
現在這樣兩個 api:
http://localhost:80/api/login
/api/login
devServe.proxy 匹配哪個?
會匹配第二個,因為第二個以
/api
開頭,而第一個以http
開頭。
value: 物件鍵的 value 是個字串,用來替換 key 匹配的字串。
有了上面的知識,那我們就可以明白 pathRewrite 的工作原理以及結果是什麼。
例如:
有這樣的 api:
/getUserInfo
,其所在的伺服器為http://192.168.0.169
。那這個 api 的url 就應該是http://192.168.0.169/getUserInfo
。然後在 axios 設定的 route 是
/api/getUserinfo
。那為了能正常存取。就需要做如下設定:
module.exports = { proxy: { '/api': { target: 'http://192.168.0.169', pathRewrite: {"^/api" : ""} } } };
這樣設定之後,devServer.proxy 就能把 url 改寫成
http://192.168.0.169/getUserInfo
關於devServer.proxy 更詳細的用法可查閱:《vue-cli 3.0之跨域請求devServer代理設定》
在閱讀 Vue 官方檔案說明時,你可能會看見這樣的寫法:
module.exports = {
devServer: {
proxy: 'http://localhost:4000'
}
}
上面其實是一種簡寫。等同於:
module.exports = {
proxy: {
'/api': {
target: 'http://localhost:4000'
}
}
};
這部分的解釋可以再http-proxy-middleware外掛的說明檔案中看到。地址如下:https://github.com/chimurai/http-proxy-middleware
vue-cli 3.0之跨域請求devServer代理設定
vue-cli 設定參考
http-proxy-middleware
devserver-proxy
URI's fragment