一、是什么
webpack proxy
,即webpack
提供的代理服務
基本行為就是接收客戶端發送的請求后轉發給其他服務器
其目的是為了便於開發者在開發模式下解決跨域問題(瀏覽器安全策略限制)
想要實現代理首先需要一個中間服務器,webpack
中提供服務器的工具為webpack-dev-server
webpack-dev-server
webpack-dev-server
是 webpack
官方推出的一款開發工具,將自動編譯和自動刷新瀏覽器等一系列對開發友好的功能全部集成在了一起
目的是為了提高開發者日常的開發效率,「只適用在開發階段」
關於配置方面,在webpack
配置對象屬性中通過devServer
屬性提供,如下:
// ./webpack.config.js
const path = require('path')
module.exports = {
// ...
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000,
proxy: {
'/api': {
target: 'https://api.github.com'
}
}
// ...
}
}
devServetr
里面proxy
則是關於代理的配置,該屬性為對象的形式,對象中每一個屬性就是一個代理的規則匹配
屬性的名稱是需要被代理的請求路徑前綴,一般為了辨別都會設置前綴為/api
,值為對應的代理匹配規則,對應如下:
- target:表示的是代理到的目標地址
- pathRewrite:默認情況下,我們的 /api-hy 也會被寫入到URL中,如果希望刪除,可以使用pathRewrite
- secure:默認情況下不接收轉發到https的服務器上,如果希望支持,可以設置為false
- changeOrigin:它表示是否更新代理后請求的 headers 中host地址
二、工作原理
proxy
工作原理實質上是利用http-proxy-middleware
這個http
代理中間件,實現請求轉發給其他服務器
舉個例子:
在開發階段,本地地址為http://localhost:3000
,該瀏覽器發送一個前綴帶有/api
標識的請求到服務端獲取數據,但響應這個請求的服務器只是將請求轉發到另一台服務器中
const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();
app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
app.listen(3000);
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
三、跨域
在開發階段, webpack-dev-server
會啟動一個本地開發服務器,所以我們的應用在開發階段是獨立運行在 localhost
的一個端口上,而后端服務又是運行在另外一個地址上
所以在開發階段中,由於瀏覽器同源策略的原因,當本地訪問后端就會出現跨域請求的問題
通過設置webpack proxy
實現代理請求后,相當於瀏覽器與服務端中添加一個代理者
當本地發送請求的時候,代理服務器響應該請求,並將請求轉發到目標服務器,目標服務器響應數據后再將數據返回給代理服務器,最終再由代理服務器將數據響應給本地
在代理服務器傳遞數據給本地瀏覽器的過程中,兩者同源,並不存在跨域行為,這時候瀏覽器就能正常接收數據
注意:「服務器與服務器之間請求數據並不會存在跨域行為,跨域行為是瀏覽器安全策略限制」
參考文獻
- https://webpack.docschina.org/configuration/dev-server/#devserverproxy