如何用Axios做HTTP请求

152 阅读12分钟

本教程包括:

  1. 为什么使用Axios?
  2. 提出Axios的POST和GET请求
  3. 测试这些请求

Axios是一个基于承诺的HTTP库,它可以让开发者向自己的或第三方的服务器发出请求以获取数据。它提供了不同的请求方式,如GETPOSTPUT/PATCHDELETE 。在本教程中,我将解释Axios如何与应用程序交互,描述Axios请求和响应的结构,如何向API发出请求,以及如何使用CircleCI为你的请求编写测试。

前提条件

要继续学习本教程,请确保你有。

我们的教程是与平台无关的,但使用CircleCI作为例子。如果你没有CircleCI账户,请**在这里注册一个免费账户。**

Axios是如何工作的?

Axios的工作原理是用NodeJS和XMLHttpRequests在浏览器上发出HTTP请求。如果请求成功,你将收到一个带有所请求数据的response 。如果request 失败,你会收到一个错误。你也可以intercept ,对请求和响应进行转换或修改。我将在本教程的后面详细介绍这个问题。

这张图显示了Axios如何与应用程序进行交互的表示。

Axios interaction

Axios能够确定请求是向浏览器还是向NodeJS发出的。一旦确定了这一点,它就会确定正确的方式来进行API请求,并将转换后的响应返回给发出服务器请求的客户端。

Axios请求和响应的配置

在Axios中做一个基本的请求很容易,因为唯一需要的选项是url 。然而,你可以根据你想做的请求类型来配置其他选项。

下面是一个请求的例子。

const axios = require('axios');

const res = await axios.get(url, {
//We can add more configurations in this object
   params: {
  //This is one of the many options we can configure
   }
});

// This is the second configuration option
const res = await axios({
    method: 'get',
    url://Endpoint goes here,
    params:{

    }
});

Axios提供了极大的灵活性来配置你的请求。你可以决定用JavaScript点符号格式调用Axios。或者你可以使用对象字面格式,将所有Axios请求属性捆绑到一个对象中,作为发出Axios请求的属性。

有几种方法是Axios支持的,并且允许提出请求。它们包括。

  • request
  • get
  • delete
  • head
  • options
  • post
  • put
  • patch

接下来的代码片断显示了如何使用Axios向Todos 样本API发送一个样本GET 请求。

axios({
    method: "get",
    url: "https://jsonplaceholder.typicode.com/todos",
    params: {
      _limit: 5
    }
  })

Axios响应

一旦你用Axios发送了一个请求,你就希望有一个响应返回。这个片段显示了Axios响应的数据结构。

{
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the response
  status: 200,

  // `statusText` is the status message from the response
  statusText: 'OK',

  // `headers` are the HTTP headers that the server responded with
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {},

  // `request` is the request that generated the response
  request: {}
}

在这个响应中,你会得到一个你期待的数据对象、服务器发回的状态代码、statusText、响应头、Axios设置的配置对象以及用于生成响应的请求对象。然后,你可以根据你需要的数据,在你的客户端应用程序上消费这些响应。

这是不是感觉有很多理论知识?如果是的话,请继续看下一节,我将向你展示如何用Axios进行HTTP请求。

提出Axios的HTTP请求

在本节中,你将提出GETPUT 请求,并观察并发请求。你将会使用一个免费的 "假 "API。JSONPlaceholder

你还将使用一个应用程序,它将帮助你提出请求,并更好地了解引擎盖下发生的事情。

在你开始之前,你需要克隆本教程的GitHub仓库。运行这些命令。

git clone https://github.com/mwaz/axios-http-requests

cd axios-http-requests

现在你应该拥有本教程所需的文件。下一步是将Axios和Jest作为依赖项安装。运行这个命令。

npm install

在浏览器上打开index.html 文件,查看你的Axios演示网页。

Axios demo webpage

现在,这些按钮不做任何事情。我们将在后面的教程中建立这些功能。

每个请求都有三个按钮。点击按钮应该在Axios请求发出并将数据返回给浏览器后显示一个响应。

在你克隆的版本库的users.js 文件中,有一个事件监听器,显示Axios返回的数据。这个文件也有你要用来提出请求的函数。开始做你的第一个GET 请求吧。

提出一个GET请求

这段代码显示了你的请求应该是什么样子的。

axios
    .get("https://jsonplaceholder.typicode.com/users/1")
    .then((response) => {
      displayOutput(response)
    })
    .catch((err) => console.log(err));

这个代码片断向JSON API发送了一个GET 请求。因为该请求返回一个承诺,你将使用.then() 块来处理响应。你还需要使用.catch() 方法来记录任何错误到控制台。

将前面的代码片段添加到users.js 文件中的getUser() 函数中,并保存它。

接下来,到浏览器中,点击GET 按钮。在它下面,应该出现新的内容,显示响应的细节。

Axios GET request

造型和显示已经完成。收到的Axios回应的部分是。

  • status 部分,显示响应的状态代码。在这种情况下,它是200 ,这意味着请求是成功的。
  • headers 部分,包含服务器响应的所有HTTP头信息。
  • data 部分,包含有效载荷或从服务器请求的信息。在这种情况下,它是所有关于user 1 的信息。
  • config 部分,它包含了为请求传递给Axios的所有配置。

如请求中所示,Axios的行为与传统的fetch-API 库一样。考虑到这是一个GET 的请求,你不需要在请求中传递一个主体。接下来我将向你展示如何使用Axios在一个POST 请求中做到这一点。

发出一个POST请求

一个post请求有点不同,因为你将在请求中向服务器传递一些数据。在请求中,你将创建一个用户并传入该用户的详细信息。请求的代码片断看起来会是这样的。

axios
    .post("https://jsonplaceholder.typicode.com/users", {
      id: 11,
      name: "Tom Brady",
      username: "Brad",
      email: "tombrad@asd.com",
    })
    .then((response) => displayOutput(response))
    .catch((err) => console.log(err));

Axios POST请求在请求URL后使用一个对象来定义你要为用户创建的属性。一旦操作完成,将有一个来自服务器的响应。为了验证你的代码是否有效,回到应用程序的浏览器窗口,点击POST按钮。这个片段是users.js 文件中postUser() 函数的一部分。

Axios POST request

POST 响应与GET 请求有一点不同。

  • status 部分的状态代码为201 ,这意味着一个资源已经被创建。在这种情况下,一个新的用户已经被创建。
  • headers 部分有一个‘content-length’ 的属性,用来表示我们发送的数据的长度。它还指定了数据的存储位置:location
  • data 部分包含了被发送到服务器的信息。
  • config 部分包含与请求一起发送的配置。这涉及到被发送的methodurl 、和data

你可以验证在你的POST 请求中定义的数据是作为创建的资源从服务器收到的确切响应。

在这一节中,你学到了如何进行Axios请求,我描述了Axios请求的基本结构及其预期响应。在下一节中,我将解释如何请求拦截,以便在数据作为请求发送到Axios之前对其进行验证。

Axios请求和响应拦截器

在Axios中,当请求在被then()catch() 代码块处理之前被拦截时就会发生。例如,假设你想检查所有进入客户端的请求是否都有一个有效的JWT令牌。你将设置一个请求拦截器,确保所有对服务器的调用都有有效的令牌。如果一个调用没有有效的令牌,系统的用户将不得不回到登录页面,重新进行认证。为了节省时间,我将带领你完成一个不太复杂的用例,为你当前的应用程序编写一个日志器。

该记录器将记录请求何时发出,请求的URL,以及请求被触发的时间。使用这个代码片段。

axios.interceptors.request.use(
      (config) => {
          const today = new Date()
      console.log(
        `${config.method.toUpperCase()} request sent to ${
          config.url
        } at ${today.getHours()} : ${today.getMinutes()}`
          );
          return config
    },
    (error) => {
        console.log(error);
    }
  );

Axios将访问你的请求的config 部分,以显示请求方法、URL和时间。这个代码片断是样本项目的interceptRequests() 函数中的users.js 文件的一部分。为了观察Axios拦截器的行为,打开Chrome浏览器控制台。点击API中获取第一个用户的GET 方法。

Axios POST request

为了使拦截器工作,它们需要作为并发请求被调用到jsonplaceholder API。接下来的代码片段显示了实现请求和响应的Axios方法。

const concurrentRequests = () => {
    interceptRequests()
  axios
    .all([
      axios.get("https://jsonplaceholder.typicode.com/users?_limit=5"),
      axios.get("https://jsonplaceholder.typicode.com/albums?_limit=5"),
    ])
    .then(
      axios.spread((users, albums) => {
        displayOutput(albums);
      })
    )
    .catch((err) => console.log(err));
};

Chrome DevTools的图片显示,当你提出任何请求时,你可以在Axios向API服务器发送请求之前修改或检查它。Axios拦截器不仅功能强大,而且让开发者有能力控制请求及其响应的行为。

现在你已经学会了如何使用拦截器来修改或检查你的Axios请求和响应。干得好!你的下一个任务是为你的Axios实现编写测试。

测试Axios的实现

编写测试是几乎所有应用程序开发中不可或缺的过程。测试有助于确保你的应用程序按预期运行,并且在整个开发过程中质量是一致的。在本教程的这一部分,你将使用Axios的node.js 版本。由于你在安装依赖项时已经安装了Jest,你可以马上开始编写测试。

在根目录下,创建两个文件并命名为app.jsapp.test.js 。使用app.js 作为你的请求,使用app.test.js 作为你的测试。你需要重新创建app.js 文件,以确保你可以访问使用Node.js Axios的方法--而不是在index.html 文件的script 部分定义的浏览器Axios。

app.js 文件中,你可以使用axios ,在Node.js 中发出请求。该方法使用与浏览器方法相同的请求结构。

const axios = require('axios');

const getUser = async () => {
  const getResponse = await axios
    .get("https://jsonplaceholder.typicode.com/users/1")
    .then((response) => response)
    .catch((err) => console.log(err));
  return getResponse;

  module.export = { getUser }
};

这个片段向先前使用的相同的URL发出请求,然后将响应保存到getResponse 变量中。然后它返回响应,使其他可能需要它的方法或函数可以访问它--比如我们的测试。该片段导出了该方法,使其可以在app.js 文件之外访问。

要写一个测试,将getUser 方法导入你的app.test.js 测试文件。然后按这里所示编写你的测试。

`Sample Response Object:
....
"address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874
    ......
  }`


import { getUser } from './app.js';

describe("Axios requests suite", () => {
  test("should get a single user", async () => {
    const response = await getUser();
    expect(response).not.toBeNull();
    expect(response.status).toBe(200);
    expect(response.data.address.street).toContain("Kulas");
  });
}

使用这个测试和样本响应对象,你可以验证从Axios端点调用的数据确实被返回,并且你的API调用是成功的。要运行这个测试,到你的终端,使用Jest命令npm test

 PASS  ./app.test.js (11.788 s)
  Axios requests suite
    √ should get a single user (1179 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.807 s
Ran all test suites.

成功了!现在你可以写更多的测试,针对POST 请求和使用Axios的并发请求。

在同一个文件中,添加这些测试。

test("should post a new user", async () => {
    const response = await postUser();
    expect(response).not.toBeNull();
    expect(response.status).toBe(201);
    expect(response.data.username).toBe("Brad");
  });

  test("should make simultaneous axios requests", async () => {
    const response = await concurrentRequests();
    expect(response).not.toBeNull();
    expect(response.status).toBe(200);
  });

当你完成后,重新运行你的测试。

npm run test

再一次,成功了!

npm run tests

现在你已经写好了Axios请求并对它们进行了测试,你可以为它们建立一个CI管道。使用像CircleCI这样的CI/CD工具,当变化破坏管道并导致测试失败时,每个人都会被告知。这种反馈循环提供了一个成功的软件开发过程中所需要的洞察力和透明度。

与CircleCI集成

创建一个.circleci 文件夹,里面有一个名为config.yml 的文件。这就是CircleCI的配置文件。在该文件中,添加这个配置。

version: 2.1
jobs:
  build:
    working_directory: ~/repo
    docker:
      - image: cimg/node:14.17.1
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
      - run:
          name: install dependencies
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
          paths:
            - ./node_modules
      - run:
          name: Axios request tests
          command: npm run test
      - store_artifacts:
          path: ~/repo/axios-http-requests

这个配置定义了你的working_directory ,然后告诉CircleCI使用一个Node图像来执行你的测试。一旦设置好了,它就会检查项目的任何存储缓存。如果有的话,在安装新的依赖项之前,需要恢复它。在安装新的依赖性后,缓存被保存,测试被执行,任何生成的工件被保存。

现在你需要保存配置文件,提交,并将更改推送到你的GitHub仓库。完成后,登录CirclecI仪表板。在项目部分找到本教程的GitHub仓库。在我们的例子中,它被称为axios-http-requests 。点击Set Up Project

Setting up the project

当出现提示时,输入有你的config.yml 文件的分支的名字。对于本教程,它是main 分支。然后,单击 "设置项目"。

Setting up the project

你有一个成功的流水线构建!

Successful project build

点击build 工作流程,查看细节。

Opening build workflow

点击你想了解更多细节的步骤;例如,Axios requests tests 步骤。

Opening build workflow

每次你推送到GitHub仓库的main 分支,CircleCI都会检测到变化。CircleCI管道将再次执行,并确保你的测试套件运行,确保一个成功的持续集成过程。