Axios: 目前使用较多,支持全局配置,请求,响应的拦截器,取消请求等操作.
场景: 当我们在网站上使用上传功能上传一个图片或者视频时,突然遇到网路不好或者服务器挂了,那么此时用于展示上传的 loading 就会卡死在这,毕竟服务器挂了以后,是得不到响应的.
解决方法1: 使用axios全局配置一个超时时间,具体见官方文档.
解决方法2: 添加一个取消当前请求的按钮或者一个关闭图标
具体如下(基于vue)
Parent组件中使用两个组件,一个是Loading组件,一个是Child组件
Child组件: 发送请求获取数据(上传文件同样),将发送请求的动作的令牌,通知父组件 Parent, 父组件Parent将令牌传递给Loading组件.这就保证了Child组件与Loading组件使用的是同一个令牌,也就是所操作的是同一个请求.
令牌包含一个代表当前请求的token属性,还有一个用来取消当前请求的cancel方法.
代码实现如下:
js文件主入口需要配置axios,如IE中不支持Promise,请使用babel-polyfill,可自行百度
javascript 代码
import axios from 'axios';
Vue.prototype.$http = axios;
Parent组件
javascript 代码
<template>
<div class="hello">
<h1>{{ msg }}h1>
<Child @cancelButton="handleCancel">Child>
<Loading :source="source">Loading>
div>
template>
<script>
import Child from './Child';
import Loading from './Loading';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App',
source: null
}
},
components: {
Child,
Loading
},
methods: {
handleCancel(source) {
this.source = source; //获取到Child组件传递过来的令牌,然后将令牌通过props的形式传递给Loading组件
}
}
}
script>
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
style>
Child组件
javascript 代码
<template>
<div class="child">
111
<button @click="getData">获取数据button>
div>
template>
<script>
export default {
data() {
return {};
},
methods: {
getData() {
let _this = this;
let CancelToken = _this.$http.CancelToken;
let source = CancelToken.source();
_this.$emit("cancelButton", source); //把该请求的令牌传递给父组件
_this.$http
.get("http://jsonplaceholder.typicode.com/comments", {
cancelToken: source.token
})
.then(function(response) {
console.log(response);
})
.catch(function(msg) {
console.log(msg);
_this.$emit('cancelButton', null);
});
}
},
mounted() {}
};
script>
<style>
.child {
margin: 50px;
}
style>
Loading组件
javascript 代码
<template>
<div class="loading">
222
<button v-show="source" @click="handleCancel">取消请求button>
div>
template>
<script>
export default {
data() {
return {
}
},
props: [
'source'
],
methods: {
handleCancel() {
console.log(this.source);
this.source.cancel('123');
//一旦取消当前请求操作,cancel方法中的参数,将会被Child组件中 catch 所捕获,当然全局的响应拦截器也会捕获到该错误,该错误对象包含一个message属性,而这个属性的值正是cancel方法中所传递的参数
}
},
mounted() {
console.log(this.source);
}
}
script>