Axios 使用指南

Axios 是什么

Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。

Axios 优点

Axios 有诸多优点。在详细用法部分,我将结合例子分别讲解

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

详细用法

先用 Koa web 框架搭建一个简单的 http 服务器,提供 API 供 axios 使用。

js 复制代码
const Koa = require("koa");
const app = new Koa();
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
const router = new Router();
const cors = require("koa-cors");

app.use(bodyParser());

app.use(
  cors({
    credentials: true,
  })
);

router.get("/person", (ctx) => {
  // const { name, age } = ctx.query;
  ctx.body = {
    name: "qin",
    age: 25,
  };
});

router.post("/book", (ctx) => {
  const { title, price, ...rest } = ctx.request.body;
  ctx.body = {
    title,
    price,
    ...rest,
  };
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(3002, () => {
  console.log("server is running at port 3002");
});

app.on("error", (err) => {
  console.error(err);
});

接下来,分别分析 Axios 的功能点。

  • 从浏览器中创建 XMLHttpRequests
html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Axios</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
      // 创建 get 请求
      axios
        .get("http://localhost:3002/person")
        .then(function (res) {
          console.log(res.data); // { name: 'qin', age: 25 }
        })
        .catch(function (error) {
          console.log(error);
        });

      // 创建 post 请求
      axios
        .post("http://localhost:3002/book", {
          title: "JavaScript高级程序设计",
          price: 99,
        })
        .then(function (res) {
          console.log(res.data); // { title: "JavaScript高级程序设计", price: 99 }
        })
        .catch(function (error) {
          console.log(error);
        });
    </script>
  </body>
</html>
  • 从 node.js 创建 http 请求
js 复制代码
// index.js

const axios = require("axios");

// 创建 get 请求
axios
  .get("http://localhost:3002/person")
  .then(function (res) {
    console.log(res.data); // { name: 'qin', age: 25 }
  })
  .catch(function (error) {
    console.log(error);
  });

// 创建 post 请求
axios
  .post("http://localhost:3002/book", {
    title: "JavaScript高级程序设计",
    price: 99,
  })
  .then(function (res) {
    console.log(res.data); // { title: "JavaScript高级程序设计", price: 99 }
  })
  .catch(function (error) {
    console.log(error);
  });

然后在终端执行 node index.js。会依次看到 console.log 方法打印出结果。

js 复制代码
{ name: 'qin', age: 25 }
{ title: "JavaScript高级程序设计", price: 99 }
  • 支持 Promise API

Axios 支持 Promise API,也就是说支持 axios.get(url).then().catch()async/await 使用形式。请看下面的例子。

js 复制代码
// index.js

const axios = require("axios");

// 用法1
axios
  .get("http://localhost:3002/person")
  .then((res) => console.log(res.data)) // { name:"qin", age: 25 }
  .catch((err) => console.log(err));

然后在终端执行 node index.js。会看到

js 复制代码
console.log(result.data); // { name:"qin", age: 25 }
  • 拦截请求和响应

在请求或响应被 then 或 catch 处理前拦截它们。下面,在 Node.js 环境里,给出拦截请求和响应的例子。

js 复制代码
// index.js
const axios = require("axios");

// 添加请求拦截器
axios.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 添加响应拦截器
axios.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    return response;
  },
  function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  }
);
  • 转换请求数据和响应数据

转换请求数据 发送请求前,对传入的数据进行修改。转换响应数据 接收响应后,对接收的数据进行修改。主要是下面两个属性。

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

  return data;
}],

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

  return data;
}],

在 Node.js 环境下,来看看 transformRequesttransformResponse 使用例子。

js 复制代码
// index.js

const axios = require("axios");
const { omit } = require("lodash");

axios
  .post(
    "http://localhost:3002/book",
    {
      title: "JavaScript高级程序设计",
      price: 99,
    },
    {
      transformRequest: [
        function (data) {
          data.author = "尼古拉斯·泽卡斯";
          return data;
        },
        ...axios.defaults.transformRequest,
      ],
      transformResponse: [
        function (data) {
          return omit(JSON.parse(data), "price");
        },
        ...axios.defaults.transformResponse,
      ],
    }
  )
  .then((res) => console.log(res.data)) // { title: "JavaScript高级程序设计", author: "尼古拉斯·泽卡斯" }
  .catch((err) => console.error(err));
  • 取消请求

使用 cancel token 取消请求

Axios 的 cancel token API 基于 cancelable promises proposal,它还处于第一阶段。

可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

js 复制代码
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios
  .get("/user/12345", {
    cancelToken: source.token,
  })
  .catch(function (thrown) {
    if (axios.isCancel(thrown)) {
      console.log("Request canceled", thrown.message);
    } else {
      // 处理错误
    }
  });

// 取消请求(message 参数是可选的)
source.cancel("Operation canceled by the user.");

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

js 复制代码
var CancelToken = axios.CancelToken;
var cancel;

axios.get("/user/12345", {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  }),
});

**在前端通过 Ajax 做大文件断点续传的场景下,会使用到取消请求功能。**

// 取消请求
cancel();

Note: 可以使用同一个 cancel token 取消多个请求

  • 自动转换 JSON 数据

axios 通过设置 transformResponse,可自动转换请求返回的 JSON 数据。详情请看 axios/axios/blob/master/lib/defaults.js 部分源码。

js 复制代码
transformResponse: [function transformResponse(data) {
  /*eslint no-param-reassign:0*/
  if (typeof data === 'string') {
    try {
      data = JSON.parse(data);
    } catch (e) { /* Ignore */ }
  }
  return data;
}],
  • 客户端支持防御 XSRF

先来了解一下 XSRF,以下内容来自维基百科。

XSRF 跨站请求伪造(Cross-site request forgery),是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。

举个例子:

假如一家网站执行转账的操作 URL 地址如下:

www.examplebank.com/withdraw?ac...

那么,一个恶意攻击者可以在另一个网站上放置如下代码:

<img src="www.examplebank.com/withdraw?ac...

如果有账户名为 Alice 的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失 1000 资金。

-------我是分割线,以上内容来自维基百科-------

那么 Axios 怎么防御 XSRF 攻击呢

js 复制代码
// 添加 xsrf 请求头

// 只在标准浏览器环境中才会起作用

if (utils.isStandardBrowserEnv()) {
  var cookies = require("./../helpers/cookies");
}

// 添加 xsrf 请求头

var xsrfValue =
  (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName
    ? cookies.read(config.xsrfCookieName)
    : undefined;

if (xsrfValue) {
  requestHeaders[config.xsrfHeaderName] = xsrfValue;
}

下面来看看这个例子。

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Axios</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
      axios
        .post(
          "http://localhost:3002/book",
          {
            title: "JavaScript高级程序设计",
            price: 99,
          },
          {
            withCredentials: true,
          }
        )
        .then(function (res) {
          console.log(res.data); // { title: "JavaScript高级程序设计", price: 99 }
        })
        .catch(function (error) {
          console.log(error);
        });
    </script>
  </body>
</html>

首先,axios 会检查是否是标准的浏览器环境,然后在标准的浏览器环境中判断,如果设置了跨域请求时需要凭证且请求的域名和页面的域名相同时,读取 cookie 中 xsrf token 的值,并设置到承载 xsrf token 的值的 HTTP 请求头中。

参考链接

相关推荐
上单带刀不带妹33 分钟前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
前端风云志35 分钟前
typescript结构化类型应用两例
javascript
杨进军1 小时前
React 创建根节点 createRoot
前端·react.js·前端框架
gnip2 小时前
总结一期正则表达式
javascript·正则表达式
爱分享的程序员2 小时前
前端面试专栏-算法篇:18. 查找算法(二分查找、哈希查找)
前端·javascript·node.js
翻滚吧键盘2 小时前
vue 条件渲染(v-if v-else-if v-else v-show)
前端·javascript·vue.js
你这个年龄怎么睡得着的2 小时前
为什么 JavaScript 中 'str' 不是对象,却能调用方法?
前端·javascript·面试
南屿im2 小时前
JavaScript 手写实现防抖与节流:优化高频事件处理的利器
前端·javascript
Spider_Man2 小时前
从零开始构建React天气应用:API集成与UI设计全指南 🌤️
前端·react.js
西陵3 小时前
Nx带来极致的前端开发体验——借助CDD&TDD开发提效
前端·javascript·架构