axios详解

Posted 十九万里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了axios详解相关的知识,希望对你有一定的参考价值。

axios是干啥的

上古浏览器页面在向服务器请求数据时,因为返回的是整个页面的数据,页面都会强制刷新一下,这对于用户来讲并不是很友好。并且我们只是需要修改页面的部分数据,但是从服务器端发送的却是整个页面的数据,十分消耗网络资源。而我们只是需要修改页面的部分数据,也希望不刷新页面,因此异步网络请求就应运而生。

Ajax(Asynchronous javascript and XML):异步网络请求。Ajax能够让页面无刷新的请求数据。

实现ajax的方式有多种,如jQuery封装的ajax,原生的XMLHttpRequest,以及axios。但各种方式都有利弊

  1. 原生的XMLHttpRequest的配置和调用方式都很繁琐,实现异步请求十分麻烦
  2. jQuery的ajax相对于原生的ajax是非常好用的,但是没有必要因为要用ajax异步网络请求而引用jQuery框架

Axios,可以理解为ajax i/o system,这不是一种新技术,本质上还是对原生XMLHttpRequest的封装,可用于浏览器和nodejs的HTTP客户端,只不过它是基于Promise的,符合最新的ES规范。具备以下特点:

  1. 在浏览器中创建XMLHttpRequest请求
  2. 在node.js中发送http请求
  3. 支持Promise API
  4. 拦截请求和响应
  5. 转换请求和响应数据
  6. 取消要求
  7. 自动转换JSON数据
  8. 客户端支持防止CSRF/XSRF(跨域请求伪造)

原生XMLHttpRequest实现

原生XMLHttpRequest实现ajax请求

var request = new XMLHttpRequest(); // 创建XMLHttpRequest对象
//ajax是异步的,设置回调函数
request.onreadystatechange = function () { // 状态发生变化时,函数被回调
    if (request.readyState === 4) { // 成功完成
        // 判断响应状态码
        if (request.status === 200) {
            // 成功,通过responseText拿到响应的文本:
            return success(request.responseText);
        } else {
            // 失败,根据响应码判断失败原因:
            return fail(request.status);
        }
    } else {
        // HTTP请求还在继续...
    }
}
// 发送请求:
request.open('GET', '/api/categories');
request.setRequestHeader("Content-Type", "application/json") //设置请求头
request.send();//到这一步,请求才正式发出

   

axios介绍

axios是基于Promise的,因此可以使用Promise API

axios的请求方式:

  1. axios(config)
  2. axios.request(config)
  3. axios.get(url [,config])
  4. axios.post(url [,data [,config]])
  5. axios.put(url [,data [,config]])
  6. axios.delete(url [,config])
  7. axios.patch(url [,data [,config]])
  8. axios.head(url [,config])
//执行GET请求
import axios from 'axios'
axios.default.baseURL = 'http://localhost:3000/api/products'
axios.get('/user?ID=12345')  //返回的是一个Promise
    .then(res=>console.log(res))
    .catch(err=>console.log(err));

//可配置参数的方式
axios.get(’/user’,{
params:{
ID:12345
}
}).then(res=>console.log(res))
.catch(err=>console.log(err));

//发送post请求
axios.post('/user',{
    firstName: 'simon',
    lastName:'li'
}).then(res=>console.log(res))
    .catch(err=>console.log(err));

发送并发请求

通过axios.all(iterable)可实现发送多个请求,参数不一定是数组,只要有iterable接口就行,函数返回的是一个数组

axios.spread(callback)可用于将结果数组展开

//发送多个请求(并发请求),类似于promise.all,若一个请求出错,那就会停止请求
const get1 = axios.get('/user/12345');
const get2 = axios.get('/user/12345/permission');
axios.all([get1,get2])
    .then(axios.spread((res1,res2)=>{
    	console.log(res1,res2);
	}))
    .catch(err=>console.log(err))

 

axios API

axios(config)可通过设置一些属性来发送请求

//发送post请求
axios({
    method: 'post',  //请求方式,默认是get请求
    url:'/user/12345', //地址
    data:{ //参数
        firstName: 'simon',
        lastName: 'li'
    }
});

 

创建一个实例

可用axios,create([config])来创建一个新的实例,并设置相关属性

const instance = axios.create({
    baseURL: 'http://localhost:3000/api/products',
    timeout: 1000,
    headers: {'X-Custom-Header':'foobar'}
});
//instance的使用
instance.get('/user',{
    params:{ID:12345}
}).then(res=>console.log(res))
.catch(err=>console.log(err))

 

Config配置选项

{
    //服务器的地址,是必须的选项
    url: '/user',
<span class="token comment">//请求的方式,若没有则默认是get</span>
method<span class="token punctuation">:</span><span class="token string">'get'</span><span class="token punctuation">,</span>
    
<span class="token comment">//如果url不是绝对地址,则会加上baseURL</span>
baseURL<span class="token punctuation">:</span> <span class="token string">'http://localhost:3000/'</span><span class="token punctuation">,</span>
   
<span class="token comment">//transformRequest允许请求的数据在发送至服务器之前进行处理,这个属性只适用于put、post、patch方式</span>
<span class="token comment">//数组的最后一个函数必须返回一个字符串或者一个'ArrayBuffer'或'Stream'或'Buffer' 实例或'ArrayBuffer','Formdata',</span>
<span class="token comment">//若函数中用到了headers,则需要设置headers属性    </span>
transformRequest<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span>headers<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token comment">//根据需求对数据进行处理</span>
    <span class="token keyword">return</span> data<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>    

<span class="token comment">//transformResponse允许对返回的数据传入then/catch之前进行处理    </span>
transformResponse<span class="token punctuation">:</span><span class="token punctuation">[</span><span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token comment">//依需要对数据进行处理</span>
    <span class="token keyword">return</span> data<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>   

<span class="token comment">//headers是自定义的要被发送的信息头</span>
headers<span class="token punctuation">:</span> <span class="token punctuation">{<!-- --></span><span class="token string">'X-Requested-with'</span><span class="token punctuation">:</span><span class="token string">'XMLHttpRequest'</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    
<span class="token comment">//params是请求连接中的请求参数,必须是一个纯对象</span>
params<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
  <span class="token constant">ID</span><span class="token punctuation">:</span><span class="token number">12345</span>  
<span class="token punctuation">}</span><span class="token punctuation">,</span>    

<span class="token comment">//paramsSerializer用于序列化参数</span>
paramsSerializer<span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>params<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
  <span class="token keyword">return</span> Qs<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>params<span class="token punctuation">,</span><span class="token punctuation">{<!-- --></span>arrayFormat<span class="token punctuation">:</span><span class="token string">'brackets'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  
<span class="token punctuation">}</span><span class="token punctuation">,</span>     

<span class="token comment">//data是请求时作为请求体的数据——request.body</span>
<span class="token comment">//只适用于put、post、patch请求方法</span>
<span class="token comment">//浏览器:FormData,File,Blob;Node:stream</span>
data<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
  firstName<span class="token punctuation">:</span> <span class="token string">'simon'</span><span class="token punctuation">,</span>  
<span class="token punctuation">}</span><span class="token punctuation">,</span>    

<span class="token comment">//timeout定义请求的时间,单位是毫秒,如果请求时间超过设定时间,请求将停止</span>
timeout<span class="token punctuation">:</span><span class="token number">1000</span><span class="token punctuation">,</span>
    
<span class="token comment">//withCredentials表明跨跨域请求书否需要证明。</span>
withCredentials<span class="token punctuation">:</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">//默认值</span>
    
<span class="token comment">//adapter适配器,允许自定义处理请求</span>
<span class="token comment">//返回一个promise</span>
adapter<span class="token punctuation">:</span><span class="token keyword">function</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token comment">/*...*/</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>    
 
<span class="token comment">//auth表明HTTP基础的认证应该被使用,并提供证书</span>
auth<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
  username<span class="token punctuation">:</span><span class="token string">'simon'</span><span class="token punctuation">,</span>
  password<span class="token punctuation">:</span><span class="token string">'123456'</span><span class="token punctuation">,</span>    
<span class="token punctuation">}</span><span class="token punctuation">,</span>    

<span class="token comment">//responseType表明服务器返回的数据类型,这些类型包括:json/blob/document/ 		arraybuffer/text/stream    </span>
 responseType<span class="token punctuation">:</span> <span class="token string">'json'</span><span class="token punctuation">,</span>   
     
 <span class="token comment">//proxy定义服务器的主机名和端口号</span>
 <span class="token comment">//auth属性表明HTTP基本认证应该跟proxy相连接,并提供证书</span>
 <span class="token comment">//这将设置一个'Proxy-Authorization'头(header),覆盖原来自定义的</span>
 proxy<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
     host<span class="token punctuation">:</span><span class="token number">127.0</span><span class="token number">.0</span><span class="token number">.1</span><span class="token punctuation">,</span>
     port<span class="token punctuation">:</span><span class="token number">8080</span><span class="token punctuation">,</span>
     auth<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
         username<span class="token punctuation">:</span><span class="token string">'simon'</span><span class="token punctuation">,</span>
         password<span class="token punctuation">:</span><span class="token string">'123456'</span>    
     <span class="token punctuation">}</span>    
 <span class="token punctuation">}</span><span class="token punctuation">,</span>   
 
 <span class="token comment">//取消请求</span>
 cancelToken<span class="token punctuation">:</span> <span class="token keyword">new</span> <span class="token class-name">CancelToken</span><span class="token punctuation">(</span>cancel<span class="token operator">=&gt;</span><span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">)</span>    

}

  • 默认设置

    可以给axios或者axios实例添加默认设置,这样当使用时将默认带上相应的信息,避免每次请求都重复操作

    全局默认设置

    全局默认设置是指给axios添加一些默认设置,如baseURL等,后面发送请求时,所有请求都会带上这些设置

    import axios from 'axios'
    axios.default.baseURL = 'http://localhost/api/';
    axios.default.headers.common['Authorization'] = AUTH_TOKEN;
    
      
    • 1
    • 2
    • 3

    实例中自定义默认值

    也可以先实例化一个axios,再给这个实例添加一些默认设置,实例去发送请求时便会带上这些设置,但不会影响其他的实例或全局axios

    const instance = axios.create({
        //创建实例时就进行默认设置
        baseURL: 'http://localhost:3000/api',
    });
    //在实例外进行默认设置
    instance.default.headers.common['Authorization'] = AUTH_TOKEN;
    
      
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设置的优先级

    设置是可以被覆盖的,设置包括了全局默认设置,实例默认设置以及请求中config中的默认设置,越往后,优先级越高,后面的会覆盖前面的设置

    import axios from 'axios'
    axios.default.timeout = 1000; //全局默认设置
    const instance = axios.create({
        timeout: 2000,  //实例默认设置
    });
    //请求时的默认设置
    instance.get('/users/123456',{
        timeout: 3000,  //最后这个设定的时间会生效
    }).then(/*....*/).catch(/*....*/)
    
      

    响应信息(response schema)

    一个请求的返回(即响应)包含以下信息

    {
        //data是服务器提供的响应
        data:{},
    
    <span class="token comment">//服务器返回的http状态码   </span>
    status<span class="token punctuation">:</span> <span class="token number">200</span><span class="token punctuation">,</span>
     
    <span class="token comment">//statusText是服务器返回的http状态信息</span>
    statusText<span class="token punctuation">:</span> <span class="token string">'ok'</span><span class="token punctuation">,</span>
        
    <span class="token comment">//heades是服务器响应中携带的headers</span>
    headers<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    
    <span class="token comment">//config是axios进行的设置,目的是为了请求(request)</span>
    config<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">,</span> 
    

}

//使用then后,response中将包含上述信息
axios.get(’/user/12345’).then(response={
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
})

拦截器interceptors

拦截器是指当发送请求或者得到响应被then或catch处理之前对它们进行拦截,拦截后可对数据做一些处理,比如给请求数据添加头部信息,或对响应数据进行序列化,然后再传给浏览器,这些都可以在拦截器中进行

//添加一个请求拦截器
axios.interceptors.request.use(config=>{
    //在请求之前做一些事
    return config;
},err=>{
   //请求错误的时候做一些事
    return Promise.reject(err);
});

//添加一个响应拦截器
axios.interceptors.response.use(response=>{
//对返回的数据做一些处理
reutrn response;
},err=>{
//对返回的错误做一些处理
return Promise.reject(err);
});

//移除拦截器
const myInterceptor = axios.interceptors.request.use(config=>{return cofig})
axios.interceptors.request.eject(myInterceptor);

//在一个axios实例中使用拦截器
var instance = axios.create();
instance.interceptors.request.use(function(){ //});

在请求拦截中,错误拦截较少,通常都是配置相关的拦截

在响应拦截中,若成功,则主要是对数据进行过滤;若失败,则可以根据starus判断报错的状态码,来跳转到不同的错误提示页面

错误处理

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

axios.get('user/12345',{
    validateStatus:function(status){
        return status < 500;//当返回码小于等于500时视为错误
    }
});

 
">取消请求

可以使用cancel token取消一个请求,当用户搜索时,可能需要频繁的发送数据查询请求,因此当发送下一个请求时 ,需要撤销上一个请求。因此需要取消请求。

const CancelToken = axios.CancelToken;
//使用CancelToken.source工厂函数创建一个cancel token
const source = CancelToken.source(); 

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

//取消请求
source.cancel(‘操作被用户取消’);

参考链接: http://www.axios-js.com/docs/index.html

以上是关于axios详解的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段14——Vue的axios网络请求封装

vue项目axios的使用实例详解

VueAxios详解

VueAxios详解

vue|axios发送post请求详解

ajax与 axios的基础讲解(附代码及接口)