Vue-cli 创建的项目配置跨域请求(通过反向代理)---配置多个代理--axios请求
问题描述:
使用 Vue-cli 创建的项目,开发地址是 localhost:8080,需要访问 localhost:9000 或https://m.maoyan.com或http://image.baidu.com上的接口
分析原因:
不同域名之间的访问,需要跨域才能正确请求。跨域的方法很多,通常都需要后台配置
不过 Vue-cli 创建的项目,可以直接利用 Node.js 代理服务器,实现跨域请求
如果使用了 axios,可以全局配置一个 baseURL,这样就不用挨个儿修改 url 了
axios.defaults.baseURL = '/api'
大家经常用的方法:
在 config>index.js 的 dev 中添加配置项 proxyTable:
proxyTable: { //本地调试 '/api': { //这里是我配置的名字 target: 'http://m.maoyan.com', //你要请求的第三方接口 changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 pathRewrite: {'^/api': '/'} //这里重写路径运行后就代理到对应地址 /* 想请求接口是 http://m.maoyan.com/ajax/movieOnInfoList?token= target 是 目标服务器地址 本地代理服务器请求数据的时候它会把我们本地的 http:localhost:8080 替换成 http://m.maoyan.com changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 pathRewrite: {'^/api': '/'} //这里重写路径运行后就代理到对应地址 如果不写这个.我们本请求的路径是 /api/ajax/movieOnInfoList?token= , 本地代理服务器补全路径后 就是 http:localhost:8080/api/ajax/movieOnInfoList?token= 这和原 接口地址 比较 是 域名不一样(这个在target已经处理过了, 相当于一样了) , 还多了一个 /api,所 以我们要把他处理掉, 通过pathRewrite: {'^/api': '/'} ,意思是 把 '/api' 替换成 '/', 这样 本地代理服务器请求地址就变成 http:localhost:8080//ajax/movieOnInfoList?token= (接口于接口之间多写/ 没事会自动处理掉,上面也可以写成 pathRewrite: {'^/api': ''} ), 但是这样写不好, 接口于接口之间放个空 语义不强, 所以建议放个 '/' */ } },
经过上面的配置就可以这样去请求 https:m.maoyan.com 上的接口了。
async mounted(){ let data = await data = await this.$http.get('/api/ajax/movieOnInfoList?token='); console.log(data); }
我这里$http就是axios, 因为我这里把axios挂载到了vue实例上,并重命名为 $http
import axios from 'axios' //引入 axios 异步请求工具 插件 import store from './store'; Vue.prototype.$http = axios; // 把 axios 方法 通过 原型 挂载 到vue根实例上(自定义key值为$http,vue实例也是一个对象嘛,所以可以自定义), // 这样 在vue项目里哪里都可以用了,不用单个mport axios from 'axios' 引入了。 //就可以以 this.$http.get().then(function(){}).catch(function(){}) 的形式去使用了,post 请求类似 get请求。
这样对只跨域请求一个域名上的数据,就完成了。当时我们有时候要跨域请求多个域名怎么办呢?
例如: 我们即要请求 https://m.maoyan.com上的接口,又要请求 http://image.baidu.com上的接口。
这是后我们这要再配一个就代理就行了。代码如下:
proxyTable: { //本地调试 '/api': { //这里是我配置的名字 target: 'http://m.maoyan.com', //你要请求的第三方接口 changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 pathRewrite: {'^/api': '/'} //这里重写路径运行后就代理到对应地址 /* 想请求接口是 http://m.maoyan.com/ajax/movieOnInfoList?token= target 是 目标服务器地址 本地代理服务器请求数据的时候它会把我们本地的 http:localhost:8080 替换成 http://m.maoyan.com changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 pathRewrite: {'^/api': '/'} //这里重写路径运行后就代理到对应地址 如果不写这个.我们本请求的路径是 /api/ajax/movieOnInfoList?token= , 本地代理服务器补全路径后 就是 http:localhost:8080/api/ajax/movieOnInfoList?token= 这和原 接口地址 比较 是 域名不一样(这个在target已经处理过了, 相当于一样了) , 还多了一个 /api,所 以我们要把他处理掉, 通过pathRewrite: {'^/api': '/'} ,意思是 把 '/api' 替换成 '/', 这样 本地代理服务器请求地址就变成 http:localhost:8080//ajax/movieOnInfoList?token= (接口于接口之间多写/ 没事会自动处理掉,上面也可以写成 pathRewrite: {'^/api': ''} ), 但是这样写不好, 接口于接口之间放个空 语义不强, 所以建议放个 '/' */ }, //因为我们 登录页的 请求接口 是 https://i.meituan.com 所以我们要在配一个代理: //本地调试 /* 注意这里不能用 '/api/baidu' 因为 这样当你到调用的时候 (原始接口: http://image.baidu.com/search/wisejsonala?tn=wisejsonala&ie=utf8&cur=result&word=%E6%91%84%E5%BD%B1%E5%B8%88%E9%99%88%E7%A3%8A&fr=&catename=&pn=0&rn=3&gsm=1e000000001e ) 你调用的是后 会这样写 this.$http.get('/api/baidu/search/wisejsonala?tn=wisejsonala&ie=utf8&cur=result&word=%E6%91%84%E5%BD%B1%E5%B8%88%E9%99%88%E7%A3%8A&fr=&catename=&pn=0&rn=3&gsm=1e000000001e') 这样就 会先匹配到 '/api' 这个暗号,代理请求到 http://m.maoyan.com, 但这并不是我们想要的,所以我们得重新写一个区别于上上面的暗号。 因为这个地方因为个人爱好的问题。 要统一写 '/api' 这个形式,可以把 猫眼域名 的暗号 改成 '/api/maoyan', 把 百度域名的暗号 改成 '/api/baidu' 这样就有统一的入口 '/api' 了。 我这里不统一改了。因为上面 的 '/api' 用的地方挺多的,这里一改,其他地方也要动。 统一管理的代码: '/api/maoyan': { //这里是我配置的名字 target: 'http://m.maoyan.com', //你要请求的第三方接口 changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 pathRewrite: {'^/api/maoyan': '/'} //这里重写路径运行后就代理到对应地址 }, '/api/baidu': { //这里是我配置的名字 target: 'http://image.baidu.com', //你要请求的第三方接口 changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 pathRewrite: {'^/api/baidu': '/'} //这里重写路径运行后就代理到对应地址 } 使用时: 1: this.$http.get('/api/maoyan/ajax/movieOnInfoList?token='); 2: this.$http.get('/api/baidu/search/wisejsonala?tn=wisejsonala&ie=utf8&cur=result&word=%E6%91%84%E5%BD%B1%E5%B8%88%E9%99%88%E7%A3%8A&fr=&catename=&pn=0&rn=3&gsm=1e000000001e'); */ '/baidu': { //这里是我配置的名字 target: 'http://image.baidu.com', //你要请求的第三方接口 changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 pathRewrite: {'^/baidu': '/'} //这里重写路径运行后就代理到对应地址 } },
测试使用'/baidu' :
async mounted(){ // let data = await this.$http.post('https://i.meituan.com/account/custom/mobilelogincode2'); let data = await this.$http.get('/baidu/search/wisejsonala?tn=wisejsonala&ie=utf8&cur=result&word=%E6%91%84%E5%BD%B1%E5%B8%88%E9%99%88%E7%A3%8A&fr=&catename=&pn=0&rn=3&gsm=1e000000001e'); console.log(data); }
输出:
成功了。
上面注释挺多的,可能看着眼晕,我在附一张简单 的。
这样就实现了跨域向多个域名请求了。