关于详解vue中的代理proxy
问题
我们本地调试一般都是 npm run serve,然后打开 本机ip:8080(localhost:8080)对吧,这时候我们要调接口调试,后端的接口的地址可能在测试环境,也可能是自己电脑的 ip,总之不是你的 lcoalhost:8080,那么你调接口就会产生跨域,那么怎么办呢?就需要proxy出场了
复习一下跨域的解决方案
jsonp
cors
Node中间件代理(两次跨域)
nginx反向代理
CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案
JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。
日常工作中,生产环境用得比较多的跨域方案是cors和nginx反向代理。
本地项目中调试用的最多的就是 node 代理,当然像 nginx、charles(抓包工具)做代理也可以,只要你会配置。
原理
vue 中的 proxy 就是利用了 Node 代理,原理还是因为服务器端没有跨域这一说嘛,也是用了这么一个插件 地址
场景
1、假设你要调取的接口是 http://e.dxy.net/api/test,然后你可以在本地调 localhost:8080/api/test,如axios.get('/api/test')
配置代理后,会做如下转发:
localhost:8080/api/test -> http://e.dxy.net/api/test localhost:8080/bcma/api/test -> http://e.dxy.net/bcma/api/test //vue-cli3.0 里面的 vue.config.js做配置 devServer: { proxy: { '/api': { target: 'http://e.dxy.net', // 后台接口域名 ws: true, //如果要代理 websockets,配置这个参数 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, //是否跨域 } } }
有新手朋友可能会问:这样做是不是只是本地调试这样做,线上怎么办呢?
我们一般调接口 axios.get('/api/test'),这样调是自动请求的当前域名,也就是本地就调用 localhost:8080,到了线上就是你们自己的服务域名,所以这个只是为了本地调试使用。当然,如果你要同时调用很多个不同的域名服务,那你调用的时候就要把相关的域名明确写出来,如axios.get('http://e.dxy.net/api/test')
2、当你调接口后端的命名没有统一给接口前加 /api 这类的标识,那么你可以自己加,也就是你可以在本地调 localhost:8080/api/test,如axios.get('/api/test'),而你要的目标接口是 http://e.dxy.net/test,你就可以用 pathRewrite,遇到 /api 就去找代理 http://e.dxy.net 并且把 /api 重写为 /。
所以转发效果就是:
localhost:8080/api/test -> http://e.dxy.net/test //vue-cli3.0 里面的 vue.config.js做配置 devServer: { proxy: { '/api': { target: 'http://e.dxy.net', // 后台接口域名 ws: true, //如果要代理 websockets,配置这个参数 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, //是否跨域 pathRewrite:{ '^/api': '/' } } } }
3、这个是对所有的接口都代理的,不止是检测到 /api 的接口,比如:
localhost:8080/api/test -> http://e.dxy.net/api/test localhost:8080/test -> http://e.dxy.net/test devServer: { proxy: 'http://e.dxy.net' }
扩展几个常用的devServer配置
完整版
1、 devServer.disableHostCheck
当设置为true时,此选项将绕过主机检查。不建议这样做,因为不检查主机的应用程序容易受到DNS重新绑定攻击。
module.exports = { //... devServer: { disableHostCheck: true } };
2、devServer.publicPath
假设服务器在http://localhost:8080下运行,output.filename设置为bundle.js。默认情况下,devServer.publicPath是/,所以您的包可以作为http://localhost:8080/bundle.js 使用。将devServer.publicPath更改为 /assets/ 就变为 http://localhost:8080/assets/bundle.js
module.exports = { //... devServer: { publicPath: '/assets/' } };
确保devServer.publicPath始终以正斜杠开头和结尾。
1、proxy里面是个大对象,如果有多个代理,直接在后面加子对象,实际开发中可能不止接口代理还有图片上传下载代理。
2、整个代理流程如何?
①首先得知道什么是代理,为什么需要代理?
代理:顾名思义就是代替别人做某事,到开发中也是这样,因为本地开发时基于node服务器进行开发,是不能直接请求后端的接口,一旦直接请求会报跨域错误,(不信可以试试把url直接写成后端地址,这时就会报错)如果这样的话,那如果知道后端地址,任何一台电脑都可访问了,所以处于各种考虑,禁止本地直接发起请求,必须要让中间一个人代替你去完成,这时候就诞生了代理。
②流程:
‘/api’:他是指遇到这个字符开头的话,在这个字符前面加上target里面的ip或者域名。
比如:/api,前的localhost:9999变成target的内容
完整的路径变成了http:xxx/xxx/api/manager/manager
但是有个问题,实际接口当中没有这个api,所以下面的pathwrite重写就解决这个问题的。他识别到api开头就会把/api重写成空,那就是不存在这个/apil了,完整的路径又变成:http:xxx/xxx/manager/manager
这里有个小小的问题(如图):实际开发中我们会发现有的人target域名后携带/,然后重写的时候也会有个/,按照上述转换的话就会多出斜杠,首先这个理解没错的,但实际上vue的代理中间件会自动处理成合规合法的地址,所以加不加都行。
鉴于文字太麻烦,我把流程写在图上吧
原文链接:https://blog.csdn.net/weixin_43972437/article/details/107291071
原文链接:https://blog.csdn.net/X_W123/article/details/120369610