Fork me on GitHub

axios 学习笔记

基本介绍

  • 官方文档地址:https://github.com/axios/axios
  • axios 是一个基于 Promise 的HTTP库,可以用在浏览器node.js中。
  • 特性:
    • 从浏览器发起 XMLHttpRequests 请求
    • 从 node.js 发起 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求和响应数据
    • 取消请求
    • 自动转换为 JSON 数据
    • 客户端支持防御 XSRF

回顾Promise

  • Promise是es6中新增的异步事件处理方式,基本用法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    let myFirstPromise = new Promise((resolve, reject)=>{ 
    // 当异步事件处理成功后自动调用 resolve(...)方法,如果失败的话则调用 reject(...)
    // 在这个例子中,我们使用setTimeout(...) 定时器来模拟异步事件
    setTimeout(function(){
    resolve("Success!"); // 此时,所有代码运行完毕
    }, 250);
    });

    myFirstPromise.then((successMessage) => {
    //successMessage 就是上面的resolve(...)方法中所传入的参数
    console.log("Yay! " + successMessage);
    });


    // Yay! Success!
  • Promise对象是一个构造函数,它接收一个函数作为参数,该函数的两个参数分别是resolvereject,它们是两个函数,由 js 引擎提供,不用自己部署。

  • resolve 函数的作用是,将 Promise 对象的状态从“未完成(pending)”变为“成功(resolved)”,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
  • reject 函数的作用是,将 Promise 对象的状态从“未完成(pending)”变为“失败(rejected)”,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
  • 上例中,myFirstPromise是Promise对象创建的一个实例,Promise实例生成后,可以用then方法分别指定resolve状态和 reject状态的回调函数,reject函数是可选的,不一定要提供。

    1
    2
    3
    4
    5
    6
    getJSON('/posts.json').then(function(posts) {
    // ...
    }).catch(function(error) {
    // 处理 getJSON 和 前一个回调函数运行时发生的错误
    console.log('发生错误!', error);
    });
  • 上面代码中,getJSON 方法返回一个 Promise 对象,如果该对象状态变为 resolved,则会调用 then 方法指定的回调函数;如果异步操作抛出异常,状态就会变为 rejected,同时调用 catch 方法指定的回调函数,处理这个错误。另外,then 方法指定的回调函数,如果在运行中抛出错误,也会被 catch 方法捕获。

axios

安装

1
2
3
4
5
// 命令行输入
npm install axios

//引入 axios
import axios from 'axios'

官网提供的示例

  • 执行 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
    // 为给定 ID 的 user 发起请求
    axios.get('/user?ID=12345')
    .then((response)=>{
    console.log(response);
    })
    .catch(function (error) {
    console.log(error);
    });

    // 上面的请求也可以这么做
    axios.get('/user', {
    params: {
    ID: 12345
    }
    }).then((response)=>{
    console.log(response);
    }).catch((error)=>{
    console.log(error);
    });
    // 使用第二种方式会对参数值执行encodeURIComponent

    // 使用async/await的方式
    async function getUser() {
    try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
    } catch (error) {
    console.error(error);
    }
    }
  • 执行 POST 请求:

    1
    2
    3
    4
    5
    6
    7
    8
    axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
    }).then((response)=>{
    console.log(response);
    }).catch((error)=>{
    console.log(error);
    });
  • 执行多个并发请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function getUserAccount() {
    return axios.get('/user/12345');
    }

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

    axios.all([getUserAccount(), getUserPermissions()])
    .then(axios.spread(function (acct, perms) {
    // 两个请求都已完成
    }));

axios API

  • 可以通过向 axios 传递相关配置来创建请求:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    axios(config)

    // 发送一个 POST 请求
    axios({
    method: 'post',
    url: '/user/12345',
    data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
    }
    });
    // 从远程图片获取 GET 请求
    axios({
    method:'get',
    url:'http://bit.ly/2mTM3nY',
    responseType:'stream'
    }).then((response)=>{
    response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
    });

    axios(url[, config])

    // 发送一个 GET 请求(默认方法)
    axios('/user/12345');

请求方法的别名

  • 为方便起见,所有被支持的请求方法都提供了别名:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    axios.request(config)

    axios.get(url[, config])

    axios.delete(url[, config])

    axios.head(url[, config])

    axios.options(url[, config])

    axios.post(url[, data[, config]])

    axios.put(url[, data[, config]])

    axios.patch(url[, data[, config]])
  • 注意:在使用别名方法时,url、method、data 这些属性都不必在配置中指定。

请求配置

  • 以下这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 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
    120
    121
    122
    123
    124
    125
    {
    // `url` 是用于请求的服务器 URL
    url: '/user',

    // `method` 是创建请求时使用的方法
    method: 'get', // 默认是 get

    // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
    // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
    baseURL: 'https://some-domain.com/api/',

    // `transformRequest` 允许在向服务器发送前,修改请求数据
    // 只能用在 'PUT', 'POST''PATCH' 这几个请求方法
    // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
    transformRequest: [function (data) {
    // 对 data 进行任意转换处理

    return data;
    }],

    // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
    transformResponse: [function (data) {
    // 对 data 进行任意转换处理

    return data;
    }],

    // `headers` 是即将被发送的自定义请求头
    headers: {'X-Requested-With': 'XMLHttpRequest'},

    // `params` 是即将与请求一起发送的 URL 参数
    // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
    params: {
    ID: 12345
    },

    // `paramsSerializer` 是一个负责 `params` 序列化的函数
    // (e.g. https://www.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` 指定请求超时的毫秒数(0 表示无超时时间)
    // 如果请求话费了超过 `timeout` 的时间,请求将被中断
    timeout: 1000,

    // `withCredentials` 表示跨域请求时是否需要使用凭证
    withCredentials: false, // 默认的

    // `adapter` 允许自定义处理请求,以使测试更轻松
    // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
    adapter: function (config) {
    /* ... */
    },

    // `auth` 表示应该使用 HTTP 基础验证,并提供凭据
    // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
    auth: {
    username: 'janedoe',
    password: 's00pers3cret'
    },

    // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
    responseType: 'json', // 默认的

    // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
    xsrfCookieName: 'XSRF-TOKEN', // default

    // `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称
    xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的

    // `onUploadProgress` 允许为上传处理进度事件
    onUploadProgress: function (progressEvent) {
    // 对原生进度事件的处理
    },

    // `onDownloadProgress` 允许为下载处理进度事件
    onDownloadProgress: function (progressEvent) {
    // 对原生进度事件的处理
    },

    // `maxContentLength` 定义允许的响应内容的最大尺寸
    maxContentLength: 2000,

    // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
    validateStatus: function (status) {
    return status >= 200 && status < 300; // 默认的
    },

    // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
    // 如果设置为0,将不会 follow 任何重定向
    maxRedirects: 5, // 默认的

    // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
    // `keepAlive` 默认没有启用
    httpAgent: new http.Agent({ keepAlive: true }),
    httpsAgent: new https.Agent({ keepAlive: true }),

    // 'proxy' 定义代理服务器的主机名称和端口
    // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
    // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
    proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: : {
    username: 'mikeymike',
    password: 'rapunz3l'
    }
    },

    // `cancelToken` 指定用于取消请求的 cancel token
    // (查看后面的 Cancellation 这节了解更多)
    cancelToken: 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: {},

    // `config` 是为请求提供的配置信息
    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);
    });

使用 axios 实现 ajax 方案

Vue-axios 与 Jquery-ajax 的使用区别
  • axios 和 ajax 的使用方法基本一样,只有个别参数不同:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // axios
    axios({
    url: 'http://jsonplaceholder.typicode.com/users',
    method: 'get',
    responseType: 'json', // 默认的
    data: {
    //'a': 1,
    //'b': 2,
    }
    }).then((response)=>{
    console.log(response);
    console.log(response.data);
    }).catch((error)=>{
    console.log(error);
    })
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // ajax
    $.ajax({
    url: 'http://jsonplaceholder.typicode.com/users',
    type: 'get',
    dataType: 'json',
    data: {
    //'a': 1,
    //'b': 2,
    },
    success: function (response) {
    console.log(response);
    }
    })
  • vue.js 自2.0版本已经不对 vue-resource 更新了,官方推荐使用 axios 解决方案。axios 使用了 Promise,而 jquery 自3.0 版本才支持 Promise,如果你只是想使用 jquery 的 ajax 的话,引入整个 jquery 是很大的负担,所以 axios 是一个很好的工具。

------ 本文结束 ------