白嫖即食:构建工具的proxy代理配置区别
前言
前几天被leader要求在组内分享一下关于这个知识,然后惨兮兮地由原来6点下班逼迫到7点,分享期间leader就在我旁边一直引导,总得来说还算不错,所以也就在这边也进行一个分享啦。
背景
当我们在进行接口联调的时候,需要对相应的接口地址发送请求,但前端和后端的域名是不一样的,所以这个时候就需要进行跨域请求,而对于跨域问题常用的方法就是在构建工具中进行代理。
目前前端开发中常用的构建工具是webpack
和 vite
,用于打包、编译和管理前端项目。今天我主要分享的是它们在配置代理服务器方面的一些不同之处,对于其他的配置就暂且不进行延申。
区别
Webpack
是一种广泛使用的前端构建工具,Webpack 不提供内置的代理功能,但你可以使用 webpack-dev-server
第三方依赖在开发时启动一个开发服务器,并通过配置实现代理。
而 vite
是新一代的一种前端构建工具,它在开发服务器中提供了内置的代理功能,并且在处理模块时采用了 ES 模块的原生支持,因此其配置和使用方式与传统的 webpack-dev-server
有些不同。
一、Webpack proxyTable
Webpack
是通过在 webpack.config.js
配置文件中的 dev
字段下添加proxyTable
选项来实现,并使用pathRewrite
来重写路径,这样就可以将开发环境中的请求代理到其他的后端服务器,解决跨域问题。例如:
// webpack.config.js
module.exports = {
// ...
dev: {
proxyTable: {
'/api': {
target: 'http://api.example.com', // 后端提供的接口
changeOrigin: true, // 是否改变请求头的HOST字段
pathRewrite: { // 重写路径,以正则表达式来重写
'^/api': ''
}
}
}
}
};
这里的配置意味着将所有以 /api
开头的请求代理到 http://api.example.com
,并且会对路径进行重写
二、Vite proxy
Vite 使用不同的方式来配置代理。你可以在 vite.config.js
文件中,使用sever
字段下的 proxy
选项来设置代理,并通过rewrite
来重写路径。与 webpack-dev-server 的 proxyTable
相比,Vite 的配置方式更加简洁和直观:
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://api.example.com', // 后端提供的接口
changeOrigin: true, // 是否改变请求头的HOST字段
rewrite: path => path.replace(/^/api/, '') // 重写路径,以正则表达式来重写
}
}
}
};
这里的配置与 webpack-dev-server 类似,将以 /api
开头的请求代理到 http://api.example.com
,并且同样会对路径进行重写。
主要区别:
- 配置文件名称:Webpack 使用的是
webpack.config.js
,而 Vite 使用的是vite.config.js
。 - 配置项名称:Webpack 使用
dev.proxyTable
,Vite 使用server.proxy
。 - 路径重写:Webpack 使用
pathRewrite
,Vite 使用rewrite
。
三、uniapp Proxy
在 uni-app
中,uni-app
也内置了代理功能,你可以通过在 manifest.json
文件中的 devServer
配置节点来设置代理。
{
"devServer": {
"proxy": {
"/api": {
"target": "http://api.example.com",
"changeOrigin": true,
"pathRewrite": {
"^/api": ""
}
}
}
}
}
总结而言,两者的功能相似,都是为了解决开发环境中的跨域问题,但 Vite 的配置更加简洁并且与其模块化的构建方式更为契合。
食用方法
比如现在后端提供的地址为http://api.example.com
,而我前端的地址为http://127.0.0.1:8080
,那就必定会遇到所谓的跨域问题 之前我的解决办法是,先配置axios的默认请求域名,axios.defaults.baseURL = '``http://api.example.com``'
,我使用的是nodejs来搭服务器的,所以配置的 access-controll-allow-orgin: ``http://127.0.0.1:8080
来解决跨域
module.exports = {
devServer: {
proxy: {
'/hls-pc': {
target: 'http://api.example.com',
changeOrigin: true,
},
},
},
};
再结合一个axios请求来进行理解
axios.get('/hls-pc/getUserInfo')
.then(response => { console.log(response.data); })
.catch(error => { console.error(error); });
当你在前端发送一个axios请求时,你实际的请求地址是http://127.0.0.1:8080/hls-pc/getUserInfo
来进行请求,但这明显是不对的,所以在dev-serer配置中,我们将以 /hls-pc开头的请求代理到target: http://api.example.com
上,即把http://127.0.0.1:8080/hls-pc/getUserInfo
替换(代理)成http://api.example.com/hls-pc/getUserInfo
,也就是把前端主机请求地址中 /hls-pc之前的全部代理成target指向的地址
不过,真正发送请求还得加上changeOrigin: true,它改变的是请求头上Host
字段,
- 如果没有使用
changeOrigin
,代理服务器会将该请求直接转发到后端 API,但是请求头中的Host
字段仍然为127.0.0.1:8080
。后端服务器接收到请求后,会检查请求头中的Host
字段,发现该域名为127.0.0.1:8080
,而不是它预期的后端域名api.example.com
。 - 后端服务器可能会认为这个请求来自一个未授权的域名,出于安全原因,它可能会拒绝这个请求,或者执行一些其他的安全策略。
- 结果就是,前端请求没有正确代理到后端 API,可能会收到跨域错误或拒绝访问等问题。
通过设置 changeOrigin: true
,代理服务器会修改请求头中的 Host
字段,将其改为后端 API 的域名 api.example.com
,这样后端服务器就会正确识别请求的来源,并且能够正常处理请求。
讲了这么多target和changOrigin的配置,基本也算掌握了webpack-dev-server的用法了,然后就是不怎么用的pathRewrite,用法和它的意思一样,重写路径,
module.exports = {
devServer: {
proxy: {
'/hls-pc/getUserInfo': {
target: 'http://api.example.com',
changeOrigin: true,
pathRewrite: {
'^/hls-pc': '',
},
},
}
}
也就是当你如果不希望传递/hls-pc
的时候,则需要重写路径:最后实际请求路径为'``http://api.example.com/getUserInfo'
,也就是按照配置'^/hls-pc': ''
,匹配到 /hls-pc的为空
整体代码为
module.exports = {
devServer: {
proxy: {
'/hls-pc/getUserInfo': {
target: 'http://api.example.com',
changeOrigin: true,
pathRewrite: {
'^/hls-pc': '',
},
},
'/hls-pc': {
target: 'http://api.example.com',
changeOrigin: true,
},
}
}
注意,配置的执行顺序是从上到下依次执行的,所以先请求的放到最上面,并且每个配置的target可以指向不同的后端接口地址,相比于access-controll-allow更加的灵活,更适合用于前端开发环境
转载自:https://juejin.cn/post/7270798856337768505