axios学习笔记

131 阅读4分钟

Axios是什么

axios是可以发送http请求的JavaScript库,在浏览器和node.js里都可以运行

Axios和Fetch的区别

相同点:

都是可以发送http请求的JavaScript库

不同点:

  • fetch是原生库,不需要安装,axios是需要安装的,不是一个原生库

  • fetch只可以浏览器运行,但是axios可以浏览器,也可以node.js运行

使用方法

  1. GET请求

    • 两种使用方法

      const axios = require('axios');
      //1.像给定用户的ID发送请求
      
      axios.get('/user?ID=12345')
          .then(function(response){
      //处理成功
              console.log(response);
      })
          .catch(function(error){
          //如果处理错误
          console.log(error)
      })
          .then(function(){
          //一定会执行
          console.log("hello")
      })
      

      也可以用这种

      const axios = require("axios")
      
      axios.get('/use',{
          params:{
              ID:12345
          }
      })
          .then(function(response){
          console.log(response)
      })
          .catch(function(error){
          console.log(error)
      })
          .then(function(){
          //总是会执行
      })
      

      支持async/await

      async function getUser(){
          try{
              const response = await.get('/user?ID=12345');
              console.log(response)
          }catch(error){
          console.log(error)
      }
      }
      
  2. POST请求

    axios.post('/user',{
        firstname:'shen',
        lastname:'xian'
    })
    .then(function(response){
        console.log(response)
    })
    .catch(function(error){
        console.log(error)
    })
    

    也可以有另外种方法

    function getUserAccount(){
        return axios.get('/user/12345')
    }
    function getUserPermissions(){
        return axios.get('/user/12345/permissions')
    }
    Promise.all([getUserAccount(),getUserPermissions()])
        .then(function(results){
        const acct = results[0];
        const perm = results[1]
    })
    

Axios API

可以向axios传递配置来创建请求

axios(config)

//发送一个post请求
axios({
    method:'post',
    url:'/user/12345',
    data:{
        firstName:'shen',
        lastName:'xian'
}
})
//在node.js用GET请求获取远程图片
axios({
    method:'get',
    url:'http://bit.ly/2mTManY',
    responsetype:'stream'
})
    .then(function(response){
        response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
})

axios(url,config)

//发送一个GET请求
axios('/user/12345')

请求方式

  1. axios.request(config)

  2. axios.get(url,config)

  3. axios.post(url,data,config)

  4. axios.delete(url,config)

  5. axios.head(url,config)

  6. axios.options(url,config)

  7. axios.put(url,data,config)

  8. axios.patch(url,data,config)

创建实例

axios.creat(config)

const instance = axios.creat({
    baseURL:'http://some-domain.com/api',
    timeout:1000,
    headers:{'X-Custom-Header':'foobar'}
})

实例方法:

  1. axios#requset(config)

  2. axios#get(url,config)

  3. axios#delete(url,config)

  4. axios#head(url,config)

  5. axios#options(url,config)

  6. axios#post(url,data,config)

  7. axios#put(url,data,config)

  8. axios.patch(url,data,config)

  9. axios#getUri

创建请求的配置选项,只有是必需的

{
    //url用于请求的服务器 URL
    url:'/user'//method是创建的使用的方法
    method:'get',//默认值
    //baseURL,将自动加在url之间,除非url是一个绝对的url
    //baseUrl以便axios实例的方法传递相对的URL
    baseURL:'https//some-domain.com/api',
    //transformRequest允许在向服务器发送前,修改请求数据
    //他只可以使用put,post,patch的请求方法
    //数组中对后一个函数返回一个字符串,一个Buffer实例,ArrayBuffer,FormData,或Stream
    transformRequest:[function(data,headers){
    //对发送的data进行任意转换处理
    return data
    }],
    //transformRequest,在传递给then,catch之前,允许修改响应数据
    transformResponse;[function(data){
    //对接受的data进行任意转换处理
    return data
    }],
    //自定义请求头
    headers:{'X-Requested-Width':'XMLHttpRequset'},
    //'params'是与请求一起发送的URL参数
    //必须是一个简单的对象或URLSearchParams对象
    params;{
        ID:12345
    },
    //paramsSerializer是可选的方法,主要用于序列化‘params’
    paramsSerializer:function(params){
        return Qs.stringify(params,{arrayFormat:'brackets'})
    }
    //data是作为请求体被发送的数据
    //仅适用于post,put,delete,和patch请求方法
    data:{
        firstName:'shen'
    },
    //发送请求体的数据的可选方法
    //请求方式post
    //只有value会被发送,key不会
    data:'Country=Brasil&City=Belo Horizonte',
    //timeout指定请求超时的毫秒数
    //如果超时,就会中断,单位毫秒
    timeout:1000,//默认为0,表示永不超时,
    //widthCredentials表示跨域请求时是否需要使用凭证
    widthCredentials:false,//默认
    //adapter允许自定义处理请求,这使测试更加容易通过
    //返回一个promise,并提交一个有效的响应
    adapter:function(config){
        /**/
    },
    //auth,HTTP的基本用户
    auth:{
        username:'summer',
        password:"123456"
    }
    //responseType:表示浏览器将要响应的数据类型
    //选项包括:arraybuffer,document,json,text,stream
    //浏览器专属‘blob’
    responseType:'json',
    //'responseEncoding'表示用于解码响应的编码(Node.js专属)
    //注意忽略responseType的值为stream
    responseEncoding:'utf-8',
    //xsrfHeaderName是带xsrf token值的http请求名称
    xsrfHeaderName:'X-XSRF-TOKEN',
    //xsrfCookieName是xsrf token值的值,被用作cookie的名称
    xsrfCookieName:'XSRF-TOKEN',
    //'onUploadProcess'允许上传进度事件
    //浏览器专属
    onUploadProcess:function(processEvent){
        //处理原生进度事件
    },
    //onDownloadProcess,允许下载进程进度事件,浏览器专属
    onDownloadProcess:function(processEvent){
        //处理原生进度事件
    },
    //maxContentLength定义了node.js中允许的HTTP响应内容的最大字节数
    maxContentLength:2000,
    //maxBodyLength,定义允许http请求内容的最大字节数
    maxBodyLength:2000// `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise
    validateStatus:function(status){
        return status >= 200 && status <= 300
    },
     // `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
    maxRedirects:5//默认值,如果为0,就不会重定向
    // `socketPath` 定义了在node.js中使用的UNIX套接字。
    socketPath: null, // default
    httpAgent: new http.Agent({ keepAlive: true }),
    httpsAgent: new https.Agent({ keepAlive: true }),
    //‘proxy’定义了定理服务器的主机名,端口号和协议
    proxy:{
        protocol:'https',
        host:'127.0.0.1',
        port:9000,
        auth:{
            username:'summer',
            password:'123456'
        }
    },
     cancelToken: new CancelToken(function (cancel) {
      }),
     decompress: true // 默认值
}

响应结构

{
    //由服务器提供的响应
    data:{},
    //状态,HTTP请求码,从服务器获得
    status:200
    //HTTP的状态信息
    statusText:'OK',
    headrs:{},      
    configs:{},
    request:{}      

使用时你将收到以下响应then

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作为第二个参数,这是错误是响应

默认配置

全局公理默认值
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';
自定义实例默认值
const instance = axios.create({
  baseURL: 'https://api.example.com'
});   
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

添加拦截器

添加一个请求拦截器
// Add a request(请求) interceptor(拦截器)
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });
添加一个响应拦截器
// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  }, function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    //任何不在2xx范围内的状态代码都会导致这个函数被触发。
    // Do something with response error
    return Promise.reject(error);
  });
删除拦截器
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
添加到自定义实例中
const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

错误处理

axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

取消请求

创建取消令牌CancelToken

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');
const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();

这是通过执行程序函数给构造函数来创建取消令牌

请求体编码

在缺省情况下,axios会将JavaScript对象序列化

浏览器

在浏览器中,可以使用URLSearchParams接口如下

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

不是所有浏览器都支持URLSearchParams

我们可以使用qs

const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));

或者以ES6的方式

import qs from 'qs';
const data = { 'bar': 123 };
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data: qs.stringify(data),
  url,
};
axios(options);

node.js

查询字符串

在node.js中可以使用querystring

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));
表单数据
const FormData = require('form-data');

const form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));

axios.post('https://example.com', form, { headers: form.getHeaders() })

或者使用拦截器

axios.interceptors.request.use(config => {
  if (config.data instanceof FormData) {
    Object.assign(config.headers, config.data.getHeaders());
  }
  return config;
});