在构建一个vue前后端分离的项目时候,需要用到百度地图提供的web服务,但是在使用axios方式发送get请求的时候,web页面不显示相应结果,在Google中按F12进入开发者模式之后,发现提示如下:
XMLHttpRequest cannot load
Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
根据网上的搜索结果,这应该是跨域调用问题,跨域问题的解决方案可以从客户端或者服务器端进行解决,由于项目调用的是公网开放的api,因此问题肯定出在前端上。
在vue-cli框架中,使用axios请求服务的语句如下:`
this.$axios
.get("http://api.map.baidu.com/place/v2/suggestion?query="+ this.query +"®ion=北京市&city_limit=false&output=json&ak=你的ak")
.then(response=>{
if(response.data){
console.log(response.data)
}
其中,所用的服务是百度地图提供的web地址检索服务,需要申请一个自己的密钥才可以使用,返回的结果为json格式。
直接调用出现如下问题:
解决方案:在vue项目的config文件夹下,找到index.js文件,在proxyTable下输入以下内容:
proxyTable: {
'/api':{
target:'http://api.map.baidu.com',
changeOrigin:true,
pathRewrite:{
'^/api':''
}
}
},
其中,target为你的目标网址,因为本项目中的api请求地址需要根据外部输入值进行动态请求,所以无法将完整路径写上,这里写第一个/号前的基本网址即可。changeOrigin为True,表示允许跨域访问,并且重写了路径接口,该段语句表示,在后续get请求中,/api将会代替http://api.map.baidu.com的部分。
因此,此时在请求服务的时候,网址变为如下即可:
this.$axios
.get("/api/place/v2/suggestion?query="+ this.query +"®ion=北京市&city_limit=false&output=json&ak=你的ak")
.then(response=>{
if(response.data){
console.log(response.data)
}
虽然这里请求的网址是/api/place/v2/suggestion?query=,但是在解析的过程中会自动将/api替换成target中提供的网址,则实际请求网址是http://api.map.baidu.com/place/v2/suggestion?,和原来是一样的。
但是为啥还是请求失败呜呜呜呜呢
如图所示,这里并没有替换成功,变成了localhost开头的网址,于是我又开始了新一轮的问题检索。。由于localhost是基本路径,因此我尝试了在main.js中将默认路径也设置为了/api:
import axios from 'axios'
Vue.prototype.$axios=axios
axios.defaults.baseURL='/api'
(这里设置之后,get中的网址中就不需要加上/api了,因为在/api处进行了拦截并且将其设置成为了默认路径)
然而,,还是依然报错,没有变化,,就在我开始怀疑百度api是不是不能用这种重写接口的方式进行调用的时候,,我重新构建了一下项目:npm run dev。
成功获取后台json。在修改配置文件后,都需要重启一次项目!这里之前没特别注意过,特此记录。
其实跨域调用还有很多方法,这个只是其中一种,本人编程小白,初学vue当作学习笔记在此记录项目新得,欢迎大家互相交流