引入
先看一個例子:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
class App extends Component {
componentDidMount(){
axios.get('http:/www.dell-lee.com/react/api/header.json').then(res=>{
console.log(res.data);
});
}
render() {
return (
<div>
Hello World
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
這是一段非常簡單的用React開發的代碼,也是一種非常常見的邏輯,在componentDidMount
中進行網絡請求。
可以看到,我們請求的URL前面的域名是寫死的。可是在實際開發過程中,可能使用的是後端提供的測試服務器,而實際上線的時候使用的是別的服務器。那麼正式上線的代碼就需要去一個個修改請求的URL。
這樣的做法顯然非常麻煩,而且還有可能出錯。
proxy
那麼解決的方案就是使用webpack-dev-server
的proxy
配置項。
{
...,
devServer: {
open: true,
hot: true,
hotOnly: true,
proxy: {
'/react/api': 'http://www.dell-lee.com'
}
}
}
而之前使用axios
請求所用的URL則可以把域名部分去掉寫成/react/api/header.json
。上面配置的含義就是當請求/react/api
這個路徑,就會自動代理到http://www.dell-lee.com/react/api
。
現在又有一個新的問題,有些時候可能接口後端還未開發完成,僅提供了一個例如說寫死數據的接口來臨時使用。
例如之前例子中的header.json
,後端未開發完成,於是提供了一個demo.json
。
同樣按照我們目前的配置,一旦後端將接口開發完成,我們需要切換接口,同樣是麻煩和易出錯。
那這個問題也能通過配置項來完成。
{
...,
devServer: {
open: true,
hot: true,
hotOnly: true,
proxy: {
'/react/api': {
target: 'http://www.dell-lee.com',
pathRewrite: {
'header.json': 'demo.json'
}
}
}
}
}
現在這個配置項相當於將header.json
重寫爲demo.json
。
於是就相當於請求了demo.json
。當需要切換接口的時候,僅需要把'header.json': 'demo.json'
這行註釋掉或刪除掉即可。
官方文檔裏還提供了幾個比較常用的配置:
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";
}
}
}
}
bypass
配置項,顧名思義就是“繞過”。這個字段對應一個函數,函數接受3個參數,分別是請求對象、相應對象、代理選項。
那麼這個例子就是繞過所有的html
資源的請求,直接返回/index.html
。
默認情況下,不接受運行在 HTTPS 上,且使用了無效證書的後端服務器。如果想要接受,修改配置如下:
proxy: {
"/api": {
target: "https://other-server.example.com",
secure: false
}
}
如果想要請求多個路徑都代理到一個域名上,換句話說請求/react/api
或者/vue/api
都代理到http://www.dell-lee.comn
可以這樣設置:
proxy: [{
context: ["/react/api", "/vue/api"],
target: "http://www.dell-lee.com",
}]