axios 是功能强大的网络请求库,基于promise的http库,可以发送get、post请求。在服务端它使用原生node.js http模块, 而在客户端 (浏览端) 则使用XMLHttpRequest。本文主要介绍JavaScript(JS)中使用axios执行get和post请求,和设置请求的timeout超时时间的方法,以及相关的示例代码。

1、引用axios

文档地址https://github.com/axios/axios

有以下几种安装引用方法,选择合适的方法即可。

1)使用npm

npm install axios

2)使用bower

bower install axios

3)使用yarn

yarn add axios

4)使用pnpm

pnpm add axios

5)使用CDN

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

2、配置和响应

1)响应格式

{
  // `data` 是由服务器提供的响应的数据
  data: {},

  // `status` HTTP状态代码来自服务器响应
  status: 200,

  // `statusText` HTTP状态消息来自服务器响应
  statusText: 'OK',

  // `headers` 服务器响应的HTTP报头
  // 所有header名称都是小写的,可以使用方括号访问。
  // 例如: `response.headers['content-type']`
  headers: {},

  // `config` 是请求提供给' axios'的配置
  config: {},

  // `request` 生成此响应的请求
  // 它是node.js中的最后一个ClientRequest实例(在重定向中)
  // 也是浏览器中的一个XMLHttpRequest实例
  request: {}
}

2)config配置

{
  // `url` 是用于请求的服务器URL
  url: '/user',

  // `method` 发出请求时使用请求方法
  method: 'get', // default

  // `baseURL` 将被放在'url'的前面,除非'url'是绝对的。
  // 为axios的实例设置' baseURL '可以方便地将相对url传递给该实例的方法。
  baseURL: 'https://some-domain.com/api/',

  // ' transformRequest '允许在请求数据发送到服务器之前更改它
  //这只适用于请求方法'PUT', 'POST', 'PATCH'和'DELETE'
  //数组中的最后一个函数必须返回一个字符串或Buffer的实例,ArrayBuffer,
  //格式化数据或流
  //可以修改头文件对象。
  transformRequest: [function (data, headers) {
    // Do whatever you want to transform the data

    return data;
  }],

  // 'transformResponse'允许对响应数据进行更改
  //传递给then/catch
  transformResponse: [function (data) {
    // 对数据进行任何转换

    return data;
  }],

  // `headers` 是要发送的自定义头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // 'params'是随请求发送的URL参数

  //必须是一个普通对象或URLSearchParams对象
  params: {
    ID: 12345
  },

  // 'paramsSerializer'是负责序列化 'params'的可选配置。
  paramsSerializer: {
    indexes: null // 数组索引格式(null -无括号,false -空括号,true -带索引的括号)
  },

  // 'data'是作为请求体发送的数据
  //只适用于请求方法'PUT', 'POST', 'DELETE, 'PATCH'
  //当没有设置' transformRequest '时,必须是以下类型之一:
  //字符串,普通对象,ArrayBuffer, ArrayBufferView, URLSearchParams
  //只有浏览器:FormData, File, Blob
  // - Node only: Stream, Buffer
  data: {
    firstName: 'Fred'
  },
  
  //语法替代发送数据到主体
  //方法后
  //只发送值,不发送键
  data: 'Country=Brasil&City=Belo Horizonte',

  // 'timeout'指定请求超时前的毫秒数。
  // 如果请求时间超过"timeout",请求将被中止。
  timeout: 1000, // 默认是 `0` (不超时)

  // 'withCredentials'表示是否跨站访问控制请求

  //应该使用凭证创建
  withCredentials: false, // default

  // 'adapter'允许自定义处理请求,这使得测试更容易。
  //返回一个承诺并提供一个有效的响应(参见lib/adapters/README.md)。
  adapter: function (config) {
    /* ... */
  },

  // 'auth'表示应该使用HTTP Basic身份验证,并提供凭据。
  //这将设置一个'Authorization'头,覆盖任何现有的
  //使用'headers'设置的'Authorization'自定义头。
  //请注意,只有HTTP基本认证可以通过该参数配置。
  //对于Bearer令牌等,使用'Authorization'自定义头。
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // responseType表示服务器将响应的数据类型
  //选项有:'arraybuffer', 'document', 'json', 'text', 'stream'
  //仅浏览器:'blob'
  responseType: 'json', // default

  // 'responseEncoding'表示解码响应时使用的编码(仅限Node.js)

  //注意:对'stream'或客户端请求的'responseType'忽略
  responseEncoding: 'utf8', // default

  // 'xsrfCookieName'是用来作为xsrf令牌值的cookie的名称
  xsrfCookieName: 'XSRF-TOKEN', // default

  // 'xsrfHeaderName'是携带xsrf令牌值的http报头名称
  xsrfHeaderName: 'X-XSRF-TOKEN', // default

  // ' onUploadProgress '允许处理上传的进度事件
  // 仅浏览器
  onUploadProgress: function (progressEvent) {
    // 对本机进度事件执行任何想要的操作
  },

  // 'onDownloadProgress'允许处理下载的进度事件
  // 仅浏览器
  onDownloadProgress: function (progressEvent) {
    // 对本机进度事件执行任何想要的操作
  },

  // 'maxContentLength'定义了node.js中允许的http响应内容的最大字节数
  maxContentLength: 2000,

  // 'maxBodyLength'(仅限节点选项)定义了http请求内容的最大字节数
  maxBodyLength: 2000,

  // 'validateStatus'定义了是否解析或拒绝给定的承诺
  // HTTP响应状态码。如果'validateStatus'返回'true'(或设置为'null')
  //或'undefined'), promise将被解决;否则,承诺将是rejected。
  validateStatus: function (status) {
    return status >= 200 && status < 300; // default
  },

    // 'maxRedirects'定义了node.js中重定向的最大数量。
  //如果设置为0,没有重定向将遵循。
  maxRedirects: 21, // default
  
  // 'beforeeredirect'定义了一个将在重定向之前调用的函数。
  //在重定向时调整请求选项
  //检查最新的响应头 
  //或者通过抛出错误来取消请求
  //如果maxRedirects设置为0,'beforeeredirect'是不使用的。
  beforeRedirect: (options, { headers }) => {
    if (options.hostname === "example.com") {
      options.auth = "user:password";
    }
  },

  // `socketPath`定义了一个要在node.js中使用的UNIX Socket。
  //'/var/run/docker.sock' 。向docker守护进程发送请求。
  //只能指定' socketPath '或'proxy'。
  //如果两者都指定,则使用'socketPath'。
  socketPath: null, // default

  // 'httpAgent'和'httpAgent'定义了执行http时使用的自定义代理

  //和HTTPS请求,分别在node.js中。这允许像这样添加选项

  //默认情况下未启用的keepAlive。
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // 'proxy'定义代理服务器的主机名、端口和协议。
  //也可以定义你的代理使用传统的' http_proxy '和
  // 'https_proxy'环境变量。如果正在使用环境变量
  //对于代理配置,也可以定义一个“no_proxy”环境
  //变量作为一个逗号分隔的不应该被代理的域列表。
  //使用'false'禁用代理,忽略环境变量。
  //“auth”表示HTTP基本身份验证应该用于连接到代理,并且
  //提供凭证。
  //这将设置一个' Proxy-Authorization '头,覆盖任何现有的
  //已经使用'headers'设置了'代理授权'自定义头。
  //如果代理服务器使用HTTPS,那么必须设置协议为'HTTPS'。
  proxy: {
    protocol: 'https',
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // 'cancelToken'指定一个取消令牌,可以用来取消请求
  //(详见取消部分)
  cancelToken: new CancelToken(function (cancel) {
  }),

  // 使用AbortController取消Axios请求的另一种方法
  signal: new AbortController().signal,

  // 'decompress'表示响应体是否应该被解压
  //自动。如果设置为'true'也会删除'content-encoding'头
  //从所有解压缩响应的响应对象
  //- Node only (XHR不能关闭解压)
  decompress: true // default

  // insecureHTTPParser 布尔类型。
  //指定在哪里使用不安全的HTTP解析器,该解析器接受无效的HTTP头。
  //这可能允许与不符合的HTTP实现互操作性。
  //应该避免使用不安全的解析器。
  //查看options https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback
  //参见https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing...
  insecureHTTPParser: undefined // default

  // 向后兼容性的transitional选项,可能在较新的版本中被删除
  transitional: {
    //静默JSON解析模式
    // 'true' -忽略JSON解析错误并设置响应。如果解析失败,数据为空(旧行为)
    // 'false' -抛出SyntaxError如果JSON解析失败(注意:responseType必须设置为'JSON')
    silentJSONParsing: true, // 当前axios版本的默认值

    // 尝试将响应字符串解析为JSON,即使'responseType'不是'JSON'
    forcedJSONParsing: true,
    
    // 请求超时时抛出ETIMEDOUT错误而不是一般的ECONNABORTED错误
    clarifyTimeoutError: false,
  },

  env: {
    // 用于自动将有效负载序列化为FormData对象的FormData类
    FormData: window?.FormData || global?.FormData
  },

  formSerializer: {
      visitor: (value, key, path, helpers)=> {}; // 自定义访问者函数操作,用于序列化表单值
      dots: boolean; // 用点代替括号格式
      metaTokens: boolean; // 在参数key中保留{}这样的特殊结尾
      indexes: boolean; // 数组索引格式为 null -无括号,false -空括号,true -带索引的括号
  }
}

3、执行get和post请求

1)执行get请求

const axios = require('axios').default;

// Make a request for a user with a given ID
axios.get('/user?ID=12345')
  .then(function (response) {
    // handle success
    console.log(response);
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
  .then(function () {
    // always executed
  });

// Optionally the request above could also be done as
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // always executed
  });  

// Want to use async/await? Add the `async` keyword to your outer function/method.
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

或者

axios({
  method: 'get',
  url: 'https://bit.ly/2mTM3nY',
  responseType: 'stream'
})
  .then(function (response) {
    response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
  });

2)执行post请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

或者

axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

为了方便起见,所有常见请求方法都提供了别名。如下,

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]])

4、设置请求的timeout超时时间

1)使用自定义创建并设置timeout时间

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});
console.log("pre call")
try
{
  await instance.post('/debug/throw')
  console.log("post call passed")
}
catch (err)
{
  console.log("post call failed")
}

2)设置全局timeout超时时间

axios.defaults.timeout = 30000;

相关文档https://github.com/axios/axios

推荐文档