七、Axios
涉及的知识:
- ES6: Promise
- ES7: async 和 await
- http协议
- ajax
- 跨域
使用axios
库发送ajax
请求
使用axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。 https://www.kancloud.cn/yunye/axios/234845
下载依赖
$ npm install axios --save
其中--save
在新版本的npm中不再被需要了,直接npm install axios
即可
引入
import axios from ‘axios’
示例:请求阿里云新闻频道数据
我们使用阿里云市场中的api作为新闻数据来源
在真实的项目中,通常是使用自己服务器的api
新闻api:https://market.aliyun.com/products/57126001/cmapi011150.html
1、在工程中创建services文件夹,并创建相应的service
相关API,在阿里云新闻api中查询
import axios from 'axios'
export async function getNewsChannels(){
let resp = await axios.get("http://ali-news.showapi.com/channelList",{
headers:{
Authorization:`APPCODE 176eadd6b4654cd5a9328c74a9025c37`
}
});
return resp.data.showapi_res_body.channelList;
}
getNewsChannels
方法帮我们返回了新闻频道数据
2、在对应的组件中显示数据
创建Channels.vue组件
<template>
<div>
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
>
<el-menu-item :index="i.toString()
" v-for="(item,i) in showChannels" :key="item.channelId">{{item.name}}</el-menu-item>
<el-menu-item><a @click="handleFold()">{{isFold?"折叠":"展开"}}</a></el-menu-item>
</el-menu>
</div>
</template>
<script>
import {getNewsChannels} from '../services/NewsService'
export default {
data() {
return {
activeIndex:"0",
isFold:false,
channels:[],
};
},
methods: {
handleFold(){
this.isFold = !this.isFold;
},
handleSelect(key, keyPath) {
console.log(key, keyPath);
},
},
computed:{
showChannels(){
if(this.isFold){
return this.channels;
}
else{
return this.channels.slice(0,6);
}
},
},
async created() {
let resp = await getNewsChannels();
console.log(resp);
this.channels = resp;
},
};
</script>
<style></style>
3、在App.vue中引入组件
<template>
<div id="app">
<el-container>
<el-header><Channels></Channels></el-header>
<el-main>Main</el-main>
</el-container>
</div>
</template>
<script>
import Header from "./components/Channels";
export default {
name: "App",
components: { Channels },
};
</script>
本地测试跨域问题
上面是为了比较轻松的解决后台数据问题,因此直接访问了阿里云的后台数据,同样,我们自己的后台数据同样可以获取,比如在NewsService有下面的代码:
export async function getUsersLocal(){
let resp = await axios.get("/api/springboot181/user/list");
return resp;
}
可以在任意地方测试一下数据是否可以获取,比如直接在main.js引用测试一下
import {getUsersLocal} from './services/NewsService'
getUsersLocal().then((resp)=>{
console.log(resp);
})
大家忽略一个问题,本地服务器,通过ajax直接访问了阿里云上的数据,其实是一个跨域的访问,简单来了域名和端口不一样,ajax请求就会出现问题
如果我们在做开发的时候,比如通过 IDEA 启动了 tomcat,比如地址是http://127.0.0.1:8080,这是后台要访问的地址
而我们做VUE前台测试的时候会通过npm run serv命令,启动一个前台服务器,比如地址是http://127.0.0.1:8081,我们需要使用前台使用axios直接访问后台接口数据的时候,就会出现下面的问题:
这就是跨域的问题,要解决这个问题,有很多办法 1、直接在应用服务器处理,我们远程访问阿里云数据的时候没有报出这个错误,其实就是阿里云后台的服务器已经处理了这个问题,这需要修改后台应用服务器的配置...
2、修改发送和响应的头文件信息,屏蔽浏览器跨域的问题 比如在前台访问后台时,加入下面的代码:
export async function getNewsChannels(){
var resp = await axios.get("http://127.0.0.1:8080/mmybatis/user.do",{
headers:{
'Content-Type':'application/x-www-form-urlencoded'
}
});
return resp;
}
主要是请求头参数:
headers:{
'Content-Type':'application/x-www-form-urlencoded'
}
后台代码中也需要加入代码:
response.setHeader("Access-Control-Allow-Origin", "*");
这种修改比较简单易懂,但是麻烦点是每个请求都需要加上请求头,而且服务器代码也需要做相应的修改,并不适合开发
3、使用webpack模式的代理 VUE导入的axios已经考虑到了跨域的问题,所以,我们可以直接使用VUE配置文件进行代理,解决跨域的问题,简单来说,就是把URL做了一次转换
需要在根目录中加入文件vue.config.js
vue.config.js
module.exports = {
lintOnSave:false, //是否在浏览器中显示代码检查的错误
devServer:{
port:8081, //设置端口号,如果默认8080不需要设置,这里设置8081主要是为了不要和后台tomcat的8080接口冲突
proxy: { //设置代理
"/api": { // /api 匹配项,匹配拦截;
target: "http://localhost:8080", //被请求的地址,需要被代理的地址
changeOrigin: true,//允许跨域
pathRewrite: {
"^/api": "" //重写配置,被代理的接口会多一个‘/api’的前缀,而原本的接口是没有的,所以需要通过此项来将接口的前缀‘/api’转换为‘’
}
}
}
}
}
这个文件在服务启动的时候会自动加载,不需要我们过多配置,但是,他的实际作用其实就是URL的改写,所以,在我们访问后台接口地址的时候,需要作出相应的改变
var resp = await axios.get("/api/mmybatis/user.do");
Comments