前言: 我們在平常本地開發時,可能經常需要與後端進行聯調,或者呼叫一些api,但是由於瀏覽器跨域的限制、開發與生產環境的差異、http與https等問題經常讓聯調的過程不夠順暢。所以本文介紹一下webpack的devServer中的proxy配置項。接下來讓我們先看一下這個配置項的基本使用:
基本使用
- 基本代理配置:如果你有一個在
localhost:3000
上的後端,你可以透過簡單的配置將/api
路由代理到這個後端伺服器。webpack會對所有本地發出的字首為/api的請求,轉發到localhost:3000
proxy: {
'/api': 'http://localhost:3000',
}
// 示例
// 假設你本地的前端服務跑在8080埠
axios.get('/api/user/info') // 會被轉發到 -> localhost:3000/api/user/info
axios.get('/user/info') // 不會被轉發, localhost:8080/user/info
- 路徑重寫:如果你不希望在代理請求時傳遞原始路徑(例如
/api
),可以使用pathRewrite
來重寫它。這裡的^/api: ''
的意思是匹配介面路徑中的/api,並將其替換為空字串
- 在這個例子中,任何以 /api 開頭的請求路徑在轉發之前都會將 /api 部分替換為空字串。例如,如果你發起一個請求到 /api/users,那麼實際傳送到後端伺服器的請求路徑將是 /users。
- ^:匹配字串的開始部分。
- target 是後端的地址
- 最後的請求路徑會是:http://localhost:3000/users
proxy: { '/api': { target: 'http://localhost:3000', pathRewrite: { '^/api': '' }, }, }
-
處理HTTPS和無效證照:預設情況下,代理不會接受執行在HTTPS上且證照無效的後端伺服器。要允許這樣的配置,可以將
secure
選項設定為false
。proxy: { '/api': { target: 'https://other-server.example.com', secure: false, }, }
-
條件代理:透過一個函式判斷是否需要代理。例如,對於瀏覽器請求,你可能希望提供一個HTML頁面,而對於API請求,則希望代理它。
proxy: { '/api': { target: 'http://localhost:3000', bypass: function (req, res, proxyOptions) { if (req.headers.accept.indexOf('html') !== -1) { console.log('Skipping proxy for browser request.'); return '/index.html'; } }, }, }
-
多路徑代理:如果你想將多個特定路徑代理到同一個目標,可以使用具有
context
屬性的物件陣列。proxy: [ { context: ['/auth', '/api'], target: 'http://localhost:3000', }, ]
-
改變原始主機頭:代理預設保持原始的主機頭。如果需要,可以透過設定
changeOrigin
為true
來改變這個行為。proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true, }, }
devServer配置示例
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口檔案配置
entry: './src/index.js',
// 輸出檔案配置
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
// 開發伺服器配置
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000,
proxy: {
// 配置代理規則 '/api'
'/api': {
target: 'http://localhost:3000', // 目標伺服器地址
pathRewrite: { '^/api': '' }, // 路徑重寫,將 '/api' 替換為 ''
secure: false, // 如果是 https 介面,需要配置為 true
changeOrigin: true // 需要虛擬託管站點
},
// 你可以在這裡繼續新增更多的代理規則
}
},
// 外掛配置
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
// 模組配置
module: {
rules: [
// 在這裡新增 loader
]
}
};
在這個配置中:
-
entry
和output
分別配置了入口和輸出檔案。 -
devServer
是開發伺服器的配置:contentBase
指定了靜態檔案的位置。compress
開啟 gzip 壓縮。port
設定開發伺服器的埠為 9000。
-
devServer.proxy
是重要的代理配置部分:- 針對任何以
/api
開始的請求,代理規則會將請求轉發到http://localhost:3000
上。 pathRewrite
將路徑中的/api
替換為空字串,這意味著例如/api/user
會被轉發為http://localhost:3000/user
。secure: false
表示接受對 https 的代理,這在目標伺服器使用自簽名證照時很有用。changeOrigin: true
用於控制Host
頭的值。如果為true
,Host
頭會被修改為目標 URL 的主機名。
- 針對任何以
-
plugins
和module
分別用於配置 Webpack 外掛和模組載入器。