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 请求头中。

参考链接

相关推荐
f8979070705 分钟前
layui动态表格出现 横竖间隔线
前端·javascript·layui
二十雨辰1 小时前
[uni-app]小兔鲜-04推荐+分类+详情
前端·javascript·uni-app
霸王蟹1 小时前
Vue3 项目中为啥不需要根标签了?
前端·javascript·vue.js·笔记·学习
lucifer3112 小时前
深入解析 React 组件封装 —— 从业务需求到性能优化
前端·react.js
儒雅的烤地瓜2 小时前
JS | 如何解决ajax无法后退的问题?
前端·javascript·ajax·pushstate·popstate事件·replacestate
觉醒法师2 小时前
Vue3+TS项目 - ref和useTemplateRef获取组件实例
开发语言·前端·javascript
老章学编程i2 小时前
Vue工程化开发
开发语言·前端·javascript·vue.js·前端框架
什么鬼昵称3 小时前
Pikachu-PHP反序列化
开发语言·javascript·php
果子切克now3 小时前
vue3导入本地图片2种实现方法
前端·javascript·vue.js
谢尔登4 小时前
【移动端】事件基础
前端·javascript·html