AXIOS
Axios基于promise的HTTP库,可以用在浏览器和node.js中。
特点
- 从浏览器中创建 XMLHttpRequests(客户端)
- 从 node.js 创建 http 请求(服务端)
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
axios和jQuery-AJAX
- 都是对AJAX的封装;
- 都有高层封装方法post/get;
- jQuery-AJAX依赖于jQuery,axios独立;
- jQuery-AJAX回调必须在内部完成,axios基于promise,可以在任意时候操作回调
- axios既提供了并发的封装,也没有fetch的各种问题,体积较小
安装axios
使用 npm:
$ npm install -S axios
使用 bower:
$ bower install axios
使用 cdn:
< script src=“https://unpkg.com/axios/dist/axios.min.js”>< /script>
demo
因为axios由promise封装,所以返回的是promise对象,可以通过then方法返回请求成功的数据信息,通过catch方法返回请求失败的数据信息。
GET方法
为给定ID的user创建请求
var pro=axios.get('/user?ID=12345') //参数拼接在路径的后面
pro.then((response)=>{
console.log(response);
}).catch((error)=>{
console.log(error);
});
//get方式的参数也可以这么指定
axios.get('/user',{
params:{ //配置项,转换为拼接字符串拼接在地址栏后面
ID:12345,//可以写多个属性
},
headers:{} //可以有多个配置项
})
POST方法
axios.post('/user',
qs.stringify(this.data), //数据,默认情况下为json格式提交,qs.stringify 转换为表单格式
{
配置信息
}).then((response)=>{
console.log(response);
}).catch((error)=>{
console.log(error);
});
AXIOS实例
axios({
//用于请求的服务器 URL
url:'getArr.php',
//methods是创建请求时使用的方法
method:'post',
//baseURL会自动加在url前面
baseURL:'http://81.69.24.232/pet/',
//transformReqest允许在向服务器发送前,修改请求数据
transformRequest:[function(data,headers){
//对data进行任意转换处理,不建议对请求头进行设置
//把数据默认转换为表单格式
console.log(data);
data.name='huang'+data.name;
console.log(data);
return qs.stringify(data); //将data数据格式化为字符串
//若未对数据进行处理,则也需要将原数据返回 return data
}],
//tansformResponse在传递给then/catch之前,允许修改响应数据
transformResponse:[function(data){
//对data进行任意转换处理
console.log(data);
return data; //会转换为json字符串
}],
// headers即将被发送的自定义请求头
headers:{
// 修改提交数据的格式(表单格式)
'Content-Type':'application/x-www-form-urlencoded',
// JSON格式
'Content-Type':'application/JSON',
// 如果项目的接口需要携带token,我们可以在头部设置token信息
'Authorization token名称':getToken()
},
//params是即将与请求一起发送的URL参数(GET中)
params: {
ID:12345
},//不可以被转换器接收
// data 是作为请求主体被发送的数据(POST方法中)
data:{
name:'zhangsan',
}, //data可以被转换器接收
//timeout为请求超时的时间(毫秒数)
timeout:5000,
//responseType服务器响应的数据类型
responseType:'json',
//maxContentLength为服务器允许的相应内容的最大尺寸(bit)
maxContentLength:2000,
})
响应结构
服务器响应的结构
{
// data 由服务器提供的响应
data: {},
// status 来自服务器响应的 HTTP 状态码
status: 200,
// statusText 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// headers 服务器响应的头
headers: {},
// config 是为请求提供的配置信息
config: {},
// request 请求信息
request: {}
}
创建实例
在项目中,我们经常需要对axios进行封装,以不同的方式请求数据;
简单来说就是创建一个axios,将基础配置设置好,然后封装不同的请求方法。
utils/axios.js
import axios from 'axios';
//axios实例,配置基础的预设配置
var myaxios=axios.create({
baseURL:'http://81.69.24.232/pet/',
headers:{
'Content-Type':'application/x-www-form-urlencoded',
// 'Authorization':getToken()
},
timeout:5000,
})
创建myaxios实例对象,可以进行请求方法的封装。
export function get(url,params){
return myaxios({
url:url,
params:params,
method:'get'
})
}
//提交表单
export function post(url,data){
return myaxios({
url:url,
data:qs.stringify(data),//表单数据格式
method:'post'
})
}
//提交json
export function post_json(url,data){
return myaxios({
url:url,
data:JSON.stringify(data),
method:'post',
headers:{
'Content-Type':'application/json', //请求头改为JSON
},
})
}
设置配置默认值
axios.defaults.baseURL = 'https://api.example.com';
//携带token
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
将axios挂载到vue原型上
main.js
import axios from 'axios'
//全局配置axios请求根路径
axios。default.baseURL='请求根路径http://www.123:3306'
//将axios挂载到全局上
Vue.prototype.$http=axios
在组件中发起请求,直接调用this.$http即可。不需要在每个组件中进行引入axios。
home.vue
async getData(){
const {data:res} = await this.$http.get('/api/get')
//路径请求根路径可以省略
优先顺序
配置会以一个优先顺序进行合并。
这个顺序是:
在 lib/defaults.js 找到的库的默认值,
然后是实例的 defaults 属性,
最后是请求的 config 参数。
后者将优先于前者。
// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();
// 覆写库的超时默认值
// 现在,在超时前,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;
// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
timeout: 5000
});
拦截器
请求前拦截:
在请求发送前,我们可以对请求的配置信息及请求头做一些处理,拦截器会暴露config(配置)属性让我们进行设置,切记在处理完毕后,返回config
//请求前拦截
myaxios.interceptors.request.use(function (config) {
console.log(config)
config.url="getData.php";
config.method="get";
config.headers['Content-Type']="application/x-www-form-urlencoded";
config.timeout='1000';
return config;//拦截后不处理时也要把数据返回
},function(err){
return Promise.reject(error);
})
响应拦截:
在请求响应后,数据接收前,我们可以对数据及请求状态进行处理,比如对复杂数据简单化的处理或者对返回的状态码进行判断,以保证返回数据是我们想要的。
//响应接收前的拦截
myAxios.interceptors.response.use(function (response) {
// 将后台的参数结果设置到response(数据封装)
let {data} = response;
response.data = data.data;
response.status = data.status;
response.statusText = data.message;
// 统一异常处理
if(data.status !== 200){
// Toast(data.message);
return Promise.reject(data.message);
}
return response;
}, function (error) {
// Toast("网络异常")
return Promise.reject(error);
});
transformer和interceptor的区别
- transformer和interceptor的执行的时机不一样,看上图
- transformer主要针对data(虽然也能直接改变header,可是不建议)
- transformer只能同步,而interceptor能够执行异步操做
别名方法
axios.request(config)
//原始的Axios请求方式
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
},
timeout: 1000,
...//其他相关配置
});
axios.get(url[, config])
axios.get('demo/url', {
params: {
id: 123,
name: 'Henry',
},
timeout: 1000,
...//其他相关配置
})
axios.delete(url[, config])
//如果服务端将参数作为java对象来封装接受
axios.delete('demo/url', {
data: {
id: 123,
name: 'Henry',
},
timeout: 1000,
...//其他相关配置
})
//如果服务端将参数作为url参数来接受,则请求的url为:www.demo/url?a=1&b=2形式
axios.delete('demo/url', {
params: {
id: 123,
name: 'Henry',
},
timeout: 1000,
...//其他相关配置
})
axios.post(url[, data[, config]])
axios.post('demo/url', {
id: 123,
name: 'Henry',
},{
timeout: 1000,
...//其他相关配置
})
axios.put(url[, data[, config]])
axios.put('demo/url', {
id: 123,
name: 'Henry',
},{
timeout: 1000,
...//其他相关配置
})
axios.patch(url[, data[, config]])
axios.patch('demo/url', {
id: 123,
name: 'Henry',
},{
timeout: 1000,
...//其他相关配置
})
以上方法的区别
- get和post
- GET参数通过URL传递,POST放在Request body中
- GET请求会被浏览器主动储存,而POST不会,除非手动设置
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
- 一般我们在浏览器输入一个网址都是GET请求
- GET产生一个TCP数据包,POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
- put和post
- PUT和POST都有更改的语义
- 如果只发送一次请求,两者表现基本一致
- 如果一次发送两个相同的请求,PUT的后一次请求会覆盖前一次(适合做修改),POST的后一次请求不会覆盖前一次请求(适合做新增)
- patch和put
- 两者都可以用于修改
- 若修改的数据只有一个字符串,则表现行为基本一致
- 若修改的是含有多个属性的对象,如果我们只修改其中一个username数据,
patch方法只传一个username到指定资源去,表示该请求是一个局部更新;
put方法则是将整个对象传到指定资源去,会造成一部分资源的浪费。
并发
多个接口同时使用
场景需求:
● 一个接口的参数会需要使用另一个接口获取
● 两个接口同时请求完数据加载页面
function getUserAccount() {
return axios.get('http://81.69.24.232/pet/getData.php');
}
function getUserPermissions() {
return axios.get('http://81.69.24.232/pet/getArr.php');
}
并发操作
getarr(){
axios.all([this.getUserAccount(),this.getUserPermissions]).then((res)=>{
console.log(res);
})
},
取消请求
场景需求:
当我们进行数据请求时,请求未成功响应就发起了下一个请求,那么可能就会出现一些意想不到的错误。
在上一个模块数据请求完成之前取消请求。
可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:
getdatab(){
let self = this;
const CancelToken = axios.CancelToken;
axios.get('http://81.69.24.232:8001/waiter/findAll',{
cancelToken: new CancelToken(function executor(c) {
self.cancel = c//取消请求的那个方法
// 这个参数 c 就是CancelToken构造函数里面自带的取消请求的函数,这里把该函数当参数用
})
})
setTimeout(function () {
//只要我们去调用了这个cancel()方法,没有完成请求的接口便会停止请求
self.cancel()
}, 100)
}