3--Axios和fetch
2020-07-09 本文已影响0人
Daeeman
Axios
1. axios 简介
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:
- 从浏览器中创建 XMLHttpRequest
- 从 node.js 发出 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防止 CSRF/XSRF
2. axios安装和引入
1. cmd安装(和cdn引入)
使用npm
npm install axios -S
使用淘宝源
cnpm install axios -S
或者使用cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2. main.js
import axios from 'axios';
Vue.prototype.$http = axios;
// 挂载axios到vue的原型公用方法上面
// 所有vue的实例都将拥有$http
3. method方法中使用
methods: {
postData () {
this.$http({
method: 'post',
url: '/user',
data: {
name: 'xiaoming',
info: '12'
}
})
}
3. 执行 GET 请求
// 向具有指定ID的用户发出请求
this.$http.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 也可以通过 params 对象传递参数
this.$http.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
完整案例(爱笑话)
<template>
<div class="about">
<van-pull-refresh v-model="isLoading" @refresh="getJoks(2)">//上拉刷新
<div class="pannel" v-for="item in joks" :key="item.docid">
<h3>{{item.title}}</h3>
<p>{{item.summary}}</p>
</div>
</van-pull-refresh>
<div style="margin:15px;">//点击加载
<van-button type="primary" block @click="getJoks(1)"> 加载更多</van-button>
</div>
</div>
</template>
<style>
.pannel{
margin: 15px;
box-shadow:0 3px 6px #eee;
border-radius: 8px;
overflow: hidden;
}
.pannel h3{
line-height: 44px;
padding: 0 15px;
font-size: 16px;
font-weight: normal;
background-color: #fafafa;
}
.pannel p{
line-height: 1.8;
color:#777;
font-size: 14px;
padding: 15px;
}
</style>
<script>
export default {
data(){return {
joks:[],
page:1,
isLoading:false,
}},
created(){
this.getJoks();
},
methods:{
getJoks(type=1){
if(type==2){
this.isLoading = true; // 显示正在加载中
}
// url 固定的后端给的地址
this.$http.get("http://www.520mg.com/mi/list.php?page="+this.page)
.then(res=>{
if(type==1){
this.joks = this.joks.concat(res.data.result.filter(item=>item.title));
}else if(type==2){
this.joks =res.data.result.filter(item=>item.title).concat(this.joks);
}
// .filter(item=>item.title); 过滤掉没有title数据
// res是后端返回的数据
// .data.result 返回的数据格式有个 data属性,data有result属性
this.page++;
this.isLoading = false; //停止加载
})
.catch(err=>{
console.log(err);
})
}
}
}
</script>
4. 执行 POST 请求
AxiosPostLogin2(value) {
// console.log("api =>" +api+" data"+data)
return new Promise((resolve, reject)=>{
console.log(value)
axios.post("http://assetsx-api-ingress.prd.10.42.226.2.k8sprd-wks.k8s.wistron.com/getNWEquipsByCondition", value,{headers: { 'Content-Type': 'application/json; charset=utf-8' }}).then((res)=>{
console.log("返回的结果是:"+JSON.stringify(res))
resolve(res.data)
})
})
}
c
this.$http.post(
url,
"k1=v1&k2=v2",// 参数
{headers:{'Content-Type':'application/x-www-form-urlencoded'}}
// 设置url编码格式
)
.then(res>{}) // 成功
.catch(err=>{}) // 失败
完整案例(电影票房数据)
<template>
<div class="about">
<h3 v-for="(item,index) in movies" :key="index">
{{item.MovieName}} --票房:{{item.amount}}万
</h3>
<input type="file" ref="file"> <button @click="upImg">上传</button>
<img :src="pic" v-if="pic" width="200" alt="">
</div>
</template>
<style></style>
<script>
export default {
data(){return {
movies:[],
pic:'',
}},
created(){
this.getMovies();
},
methods:{
upImg(){
let file = this.$refs.file.files[0];
let data = new FormData();
data.append('file',file);
let configs = {
headers:{'Content-Type':'multipart/form-data'}
}
this.$http({
method:'post',
url:'/ajax/file.php',
data,
configs
})
.then(res=>{
console.log(res);
if(res.data.error==0){
this.pic = 'http://www.520mg.com'+res.data.pic;
// 设置图片的路径
this.$refs.file.value='';
// 清空files文件
}
})
.catch(err=>console.log(err))
},
//**********************************************************************
getMovies(){
this.$http.post(
"http://www.endata.com.cn/API/GetData.ashx",
"MethodName=BoxOffice_GetPcHomeList",
// {headers:{"Content-Type":"application/x-www-form-urlencoded"}}
)
.then(res=>{
console.log(res.data);
this.movies = res.data.Data.Table1.sort((a,b)=>{return a.amount>b.amount?-1:1});
})
.catch(err=>{
console.log(err);
})
},
</script>
5. 执行 多个 请求
function getUserAccount() {
return $http.get('/user/12345');
}
function getUserPermissions() {
return $http.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then($http.spread(function (acct, perms) {
//两个请求现已完成
}));
6. 文件上传
let data = new FormData(); // 创建表单数据 data.append('file',file); // 插入表单数据 let configs = {headers:{'Content-Type':'multipart/form-data'} }; this.$http({ method:'post', //请求方法 url:"/ajax/file.php",// 请求地址 data, // 请求数据 configs, // 请求配置 }) .then(res>{}) // 成功 .catch(err=>{}) // 失败
完整案例之文件上传
<template>
<div class="about">
<input type="file" ref="file"> <button @click="upImg">上传</button>
<img :src="pic" v-if="pic" width="200" alt="">
</div>
</template>
<style></style>
<script>
export default {
data(){return {
pic:'',
}},
methods:{
upImg(){
let file = this.$refs.file.files[0];
let data = new FormData();
data.append('file',file);
let configs = {
headers:{'Content-Type':'multipart/form-data'}
}
this.$http({
method:'post',
url:'/ajax/file.php',
//url:'http://www.520mg.com/ajax/file.php',
data,
configs
})
.then(res=>{
console.log(res);
if(res.data.error==0){
this.pic = 'http://www.520mg.com'+res.data.pic;
// 设置图片的路径
this.$refs.file.value='';
// 清空files文件
}
})
.catch(err=>console.log(err))
},
</script>
7.全局配置
在 main.js中进行配置,(要写在axios挂载之前)
- 可以删除页面中 http://520mg.com
axios.defaults.baseURL = "http://520mg.com"
// 配置基础url
- 可以删除页面中 :{headers:{"Content-Type":"application/x-www-form-urlencoded"}}
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// 配置post编码
// 配置完成可以去掉页面中的post头信息(header)
- 全局配置
axios.defaults.withCredentials = true;
//跨域请求的全局凭证
8. axios本地json数据获取
- 把json拷贝到public 目录
- 发起ajax请求
this.$http.get('/js/youdata.json' )
.then(res>{}) // 成功
.catch(err=>{}) // 失败
import jsonp from 'jsonp';
jsonp(url,opts,function(err,data){
console.log("json方法",data);
})
},
opts:{prefix: '__jp',param:'callback'}
完整案例之肺炎数据获取
<template>
<div class="about">
<h1>{{add}}</h1>
<h3 v-for="(item,index) in feiyan" :key="index">
{{item.one_level_area}}
{{item.sure_cnt}}
</h3>
</div>
</template>
<style></style>
<script>
import jsonp from '../assets/js/jsonp'
export default {
data(){return {
add:'',//地址
feiyan:'',//新冠肺炎国外数据
}},
created(){
this.getAdd();
// 获取ip对应的地址
this.getFeiyan();
// 获取肺炎数据
},
methods:{
getFeiyan(){
this.$http.get("http://localhost:8080/feiyan/special?uc_param_str=pccplomi&feiyan=1&district=1&tabStart=0&tabEnd=1&tabBrief=1&aid=3804775841868884355")
// this.$http.get("http://localhost:8080/special.json")
// 本地数据存储在 /pubic/special.json
.then(res=>{
// console.log(res.data);
this.feiyan = res.data.data.feiyan.cities
.filter(item=>item.country!="中国")
.sort((a,b) => a.sure_cnt>b.sure_cnt?-1:1) ;
// 过滤掉所有中国的数据
// 数据按确诊数从大到小排序
})
.catch(err=>{
console.log("err",err);
})
},
getAdd(){
jsonp("http://api.map.baidu.com/location/ip?ak=I5p02PxH5e459CAk9vt4elbXNTkgfxde",{},
(err,data)=>{
this.add = data.content.address;
}
)
},
</script>
扩展 fetch
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log(data);
})
.catch(function(e) {
console.log("Oops, error");
});
ES6箭头函数
fetch(url)
.then(response=> response.json())
.then(data=> console.log(data))
.catch(e=> console.log("Oops, error", e))
使用 async/await
来做最终优化:
(async function(){
try {
let response = await fetch(url);
let data = response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
})();
使用 await 后,写异步代码就像写同步代码一样爽。await 后面可以跟 Promise 对象,表示等待 Promise resolve() 才会继续向下执行,如果 Promise 被 reject() 或抛出异常则会被外面的 try…catch 捕获。
http://hjingren.cn/2017/05/09/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-es6Async%E5%87%BD%E6%95%B0/
GET请求
fetch(url, {
method: "GET", //默认
headers:{
"Accept": "application/json, text/plain, */*"
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
POST请求
fetch(url, {
method: "POST",
headers: {
"Accept": "application/json, text/plain, */*",
"Content-type":"application:/x-www-form-urlencoded; charset=UTF-8"
},
body: "name=hzzly&age=22"
})
.then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
使用Fetch请求发送凭证
要使用Fetch发送带有诸如cookie之类的凭证的请求。你可以在选项对象中将credentials属性值设置为“include”:
fetch(url,{
credentials: "include"
})
封装POST请求
//将对象拼接成 name=hzzly&age=22 的字符串形式
function params(obj) {
let result = ''
for(let item in obj) {
result += `&${item}=${obj[item]}`
}
if(result) {
result = result.slice(1)
}
return result
}
function post(url, paramsObj) {
let result = fetch(url, {
methods: 'POST',
credentials: "include"
headers: {
"Accept": "application/json, text/plain, */*",
"Content-type":"application:/x-www-form-urlencoded; charset=UTF-8"
},
body: params(paramsObj)
})
return result
}
let obj = {
name: 'hzzly',
age: 22
}
post(url, obj)
.then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))