Axios:基于Promise的HTTP库

前言

在Vue1.0中我们知道和服务端通信发送请求获取数据依赖的是vue-resource,但自Vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是改成了推荐的Axios这一HTTP库。作用上类似我们熟知的一些Ajax库,但是Axios是基于Promise的HTTP请求客户端,可同时在浏览器和Node.js中使用,这好像更符合目前前端的技术新趋势。现将Axios的官方文档及示例做一介绍。

实现的功能特点

  • 可以从浏览器端发起XMLHttpRequests请求
  • node端发起http请求
  • 支持Promise API
  • 监听请求和响应
  • 转化请求和返回响应数据
  • 取消请求
  • JSON数据自动转化
  • 客户端支持防御CSRF攻击

浏览器支持

Chrome Firefox Safari Opera Edge IE
Latest ✔ Latest ✔ Latest ✔ Latest ✔ Latest ✔ 8+ ✔

Browser Matrix

安装

使用npm
1
$ npm install axios
使用bower
1
$ bower install axios
使用CDN
1
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

示例

发起一个GET请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 发起一个user请求
axios.get('/user?ID=1234')
.then(function(respone) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});

// 上面的请求也可选择下面的方式来写
axios.get('/user',{
params:{
ID:12345
}
})
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error)
});
发起一个POST请求
1
2
3
4
5
6
7
8
9
10
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
发起一个多重并发请求
1
2
3
4
5
6
7
8
9
10
11
12
13
function getUserAccount() {
return axios.get('/user/12345');
}

function getUserPermissions() {
return axios.get('/user/12345/permissions');
}

axios.all([getUerAccount(),getUserPermissions()])
.then(axios.spread(function(acc,pers){
// 两个请求现在都完成
// TODO
}));

Axios API

axios能够在进行请求时进行一些设置。

axios(config)

1
2
3
4
5
6
7
8
9
// 发起POST请求
axios({
method: 'post',
url: '/user/12345',
data:{
firstName:'Fred',
lastName:'Flintstone'
}
});
1
2
3
4
5
6
7
8
9
// 请求远程服务的一张图片
axios({
method: 'get',
url: 'http://bit.ly/2mTM3nY',
responseType: 'stream'
})
.then(function(response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});

axios(url[, config])

1
2
// 发起一个GET请求
axios('/user/12345/);

请求方法别名

为了方便axios提供了所有请求方法的别名

1
axios.request(config)
1
axios.get(url[, config])
1
axios.delete(url[, config])
1
axios.head(url[, config])
1
axios.options(url[, config])
1
axios.post(url[, data[, config]])
1
axios.put(url[, data[, config]])
1
axios.patch(url[, data[, config]])
并发

处理并发请求有用的方法

1
axios.all(iterable)
1
axios.spread(callback)

创建一个实例

你可以使用自定义设置创建一个新的实例

1
axios.create([config])
1
2
3
4
5
var instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});

请求配置

以下列出了一些请求时的设置。只有url是必须的,如果没有指明的话,默认的请求方法是GET。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
{
// url 是服务器链接接口地址
url: '/user',

// method 是发起请求时的请求方法
method: 'get',

// baseURL 如果url不是绝对地址,那么将会加在其前面
// 当axios使用相对地址时这个设置非常方便
// 在其实例中的方法
baseURL: 'http://some-domain.com/api/',

// transformRequest 允许请求的数据在传到服务器之前进行转化
// 这个只适用于PUT,GET,PATCH方法
// 数组中的最后一个函数必须返回一个字符串,一个ArrayBuffer,或者Stream
transformRequest: [function(data) {
// 依自己的需求对请求数据进行处理
return data;
}],

// transformResponse 允许返回的数据传入then/catch之前进行处理
transformResponse: [function(data) {
// 依需要对数据进行处理
return data;
}],

// headers 是自定义的要被发送的头信息
headers: {'X-Requested-with': 'XMLHttpRequest'},

// params是请求连接中的请求参数,必须是一个纯对象,或者URLSearchParams对象
params: {
ID: 12345
},

// paramsSerializer 是一个可选的函数,是用来序列化参数
// 例如:(https://ww.npmjs.com/package/qs,http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params,{arrayFormat: 'brackets'})
},

// data 是请求体需要设置的数据
// 只适用于应用的PUT,POST,PATCH请求方法
// 当没有设置transformRequest时,必须是以下其中之一的类型:
// -string,plain object,ArrayBuffer,ArrayBufferView,URLSearchParams
// -仅浏览器:FormData,File,Blob
// -仅Node:Stream
data: {
firstName: 'fred'
},
// timeout 定义请求的时间,单位是毫秒。
// 如果请求的时间超过这个设定时间,请求将会停止
timeout: 1000,

// withCredentials 表明是否跨域请求,
// 应该是用证书
withCredentials: false // 默认值

// adapter 适配器,允许自定义处理请求,这会使测试更简单
// 返回一个promise,并且提供验证返回
adapter: function(config) {

},

// auth 表明HTTP基础的认证应该被使用,并且提供证书
// 这个会设置一个authorization头(header),并且覆盖你在header设置的Authorization头信息
auth: {
username: 'janedoe',
password: 's00pers3cret'
},

// responsetype 表明服务器返回的数据类型,这些类型的设置应该是:
//'arraybuffer','blob','document','json','text',stream'
responsetype: 'json',

// xsrfHeaderName 是http头(header)的名字,并且该头携带xsrf的值
xrsfHeadername: 'X-XSRF-TOKEN',// 默认值

// onUploadProgress允许处理上传过程的事件
onUploadProgress: function(progressEvent){
//本地过程事件发生时想做的事
},

//`onDownloadProgress`允许处理下载过程的事件
onDownloadProgress: function(progressEvent) {
// 下载过程中想做的事
},

// maxContentLength 定义http返回内容的最大容量
maxContentLength: 2000,

// validateStatus 定义promise的resolve和reject
// http返回状态码,如果validateStatus返回true(或者设置成null/undefined),promise将会接受;其他的promise将会拒绝。
validateStatus: function(status) {
return status >= 200 && stauts < 300; // 默认
},

// httpAgent和httpsAgent当产生一个http或者https请求时分别定义一个自定义的代理,在nodejs中。
// 这个允许设置一些选选个,像是`keepAlive`--这个在默认中是没有开启的。
httpAgent: new http.Agent({keepAlive: treu}),
httpsAgent: new https.Agent({keepAlive: true}),

// proxy 定义服务器的主机名字和端口号
// auth表明HTTP基本认证应该跟proxy相连接,并且提供证书
// 这个将设置一个'Proxy-Authorization'头(header),覆盖原先自定义的
proxy: {
host: 127.0.0.1,
port: 9000,
auth: {
username: 'cdd',
password: '123456'
}
},

// cancelTaken定义一个取消,能够用来取消请求
//(查看下面的Cancellation的详细部分)
cancelToke: new CancelToken(function(cancel) {

})
}

响应概要

一个请求的响应包含以下信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
// data是服务器的提供的返回值
data: {},

// status是服务器返回的http状态码
status: 200,

// statusText是服务器返回的http状态信息
statusText: 'ok',

// headers是服务器返回中携带的headers
headers: {},

// config是对axios进行的设置,目的是为了请求
config: {}
}

如果你使用then,你将获取到以下响应返回结果

1
2
3
4
5
6
7
8
axios.get('/user/12345')
.then(function(response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});

使用catch时,或者传入一个reject callback作为then的第二个参数,那么返回的错误信息将能够被使用。

默认设置

你可以设置一个默认的设置将在所有的请求中有效。

全局默认设置:
1
2
3
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
实例中自定义默认值
1
2
3
4
5
6
7
// 当创建一个实例时进行默认设置
var instance = axios.create({
baseURL: 'https://api.example.com'
});

// 在实例创建之后改变默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
设置优先级

设置(config)将按照优先顺序整合起来。首先的是在 lib/defaults.js 中定义的默认设置,其次是 defaults 实例属性的设置,最后是请求中 config 参数的设置。越往后面的等级越高,会覆盖前面的设置

1
2
3
4
5
6
7
8
9
10
11
12
// 使用默认库的设置创建一个实例,
// 这个实例中使用的是默认库的timeout设置,默认值是0。
var instance = axios.create();

// 覆盖默认库中timeout的默认值
// 此时所有的请求的timeout时间是2.5秒
instance.defaults.timeout = 2500;

// 覆盖该次请求中timeout的值,这个值设置的时间更长一些
instance.get('/longRequest',{
timeout: 5000
});
拦截器

你可以在requests或者responses被then或者catch处理之前对他们进行拦截

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 添加一个请求拦截器
axios.interceptors.request.use(function(config) {
// 在请求发送之前
// TODO
return config;
},function(error) {
// 当出现请求错误
// TODO
return Promise.reject(error);
});

// 添加一个返回拦截器
axios.interceptors.response.use(function(response) {
// 对返回的数据进行处理
// TODO
return response;
},function(error) {
// 对返回的错误进行处理
//TODO
return Promise.reject(error);
});

如果你需要在稍后移除拦截器

1
2
var myInterceptor = axios.interceptors.request.use(function(){/*...*/});
axios.interceptors.rquest.eject(myInterceptor);

你可以在一个axios实例中使用拦截器

1
2
var instance = axios.create();
instance.interceptors.request.use(function(){/*...*/});
错误处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
axios.get('user/12345')
.catch(function(error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else {
// 一些错误是在设置请求时触发的
console.log('Error', error.message);
}
console.log(error.config);
});
```

可以使用validateStatus设置选项自定义HTTP状态码的错误范围。

axios.get(‘user/12345’,{
validateStatus:function(status){
return status < 500; // Reject only if the status code is greater than or equal to 500
}
});

1
2
3
4
5
6

### 取消请求

可以使用cancel token取消一个请求。

可以使用CancelToke.source工厂函数创建一个cancel token:

var source = CancelToken.source();

axios.get(‘/user/12345’, {
cancelToken:source.toke
}).catch(function(thrown) {
if (axiso.isCancel(thrown)) {
console.log(‘Rquest canceled’, thrown.message);
} else {
// handle error
// TODO
}
});

// 取消请求(信息参数是可设置的)
source.cancel(‘Operation canceled by the user.’);

1
2

可以给CancelToken构造函数传递一个executor function来创建一个cancel token:

var CancelToken = axios.CancelToken;
var cancel;

axios.get(‘/user/12345’, {
cancelToken: new CancelToken(function executor(c) {
// 这个executor函数接受一个cancel function作为参数
cancel = c;
})
});

// 取消请求
cancel();

1
2
3
4

### Node.js

在nodejs中可以如下使用querystring:

var querystring = require(‘querystring’);
axios.post(‘http://something.com/', querystring.stringify({foo:’bar’}));
`

Promises

axios基于原生的ES6 Promise实现。如果环境不支持请使用polyfill

坚持原创技术分享,您的支持将鼓励我继续创作!