基于Axios库的HTTP请求编程

2024/11/28

我们的学习方法是经典的 gpt 学习法,即助教给了两个代码让 gpt 领悟,再让 gpt 来教我们

//request.js
import axios from "axios";

const HOST = "http://10.176.26.122:8080";

export async function Get(uri, config=undefined) {
  if (config === undefined) {
    config = {
      'headers': {'Content-Type': 'application/json;charset=UTF-8'},
      'params': {},
    };
  }
  try {
    let resp = await axios.get(`${HOST}${uri}`, config);
    console.log(resp.status, resp.data);
    return resp.data;
  } catch (error) {
    console.error(error.status, error.response.data);
  }
}

export async function Post(uri, data, config=undefined) {
  if (config === undefined) {
    config = {
      'headers': {'Content-Type': 'application/json;charset=UTF-8'},
    };
  }
  try {
    let resp = await axios.post(`${HOST}${uri}`, data, config);
    console.log(resp.status, resp.data);
    return resp.data;
  } catch (error) {
    console.error(error.status, error.response.data);
  }
}

export async function Put(uri, data, config=undefined) {
  if (config === undefined) {
    config = {
      'headers': {'Content-Type': 'application/json;charset=UTF-8'},
    };
  }
  try {
    let resp = await axios.put(`${HOST}${uri}`, data, config);
    console.log(resp.status, resp.data);
    return resp.data;
  } catch (error) {
    console.error(error.status, error.response.data);
  }
}

export async function Delete(uri, config=undefined) {
  if (config === undefined) {
    config = {
      'headers': {'Content-Type': 'application/json;charset=UTF-8'},
    };
  }
  try {
    let resp = await axios.delete(`${HOST}${uri}`, config);
    console.log(resp.status, resp.data);
    return resp.data;
  } catch (error) {
    console.error(error.status, error.response.data);
  }
}
//RecordService.js
import { Get, Post, Put, Delete } from "./request.js";


async function createRecord(recordData) {
  return await Post("/api/records", recordData);
}

async function getRecordsList() {
  return await Get("/api/records");
}

async function updateRecord(id, recordData) {
  return await Put(`/api/records/${id}`, recordData);
}

async function deleteRecord(id) {
  return await Delete(`/api/records/${id}`);
}

async function test() {
  console.log("\ncreate first record...");
  let r1 = await createRecord({"text": "my post3", "visibleStatus": 0, "status": 0});

  console.log("\ncreate second record...");
  let r2 = await createRecord({"text": "my post2", "visibleStatus": 0, "status": 0});

  console.log("\ncreate third record...");
  let r3 = await createRecord({"text": "my post1", "visibleStatus": 0, "status": 0});

  console.log("\nshow record list...");
  await getRecordsList();

  console.log("\nupdate first record...");
  let newR1 = await updateRecord(r1.id, {...r1, "text": "new post3"});

  console.log("\nshow record list...");
  await getRecordsList();

  console.log("\ndelete second record...");
  await deleteRecord(r2.id);

  console.log("\nshow record list...");
  await getRecordsList();
  
  console.log("\ndelete first record...");
  await deleteRecord(r1.id);
  console.log("\ndelete third record...");
  await deleteRecord(r3.id);

  console.log("\nshow record list...");
  await getRecordsList();
}

test();

其中 HOST 是虚拟机的 ip,好现在让我们以 Get 为例解释这些函数

目的:这个函数是封装了一个 GET 请求,用于从服务器获取数据。
参数:

uri:请求的 URL 路径(相对于基础 HOST)

config:Axios 的配置对象(可选)。如果没有传入 config,则使用默认配置,包括设置 Content-Type 和空的查询参数(params)

详细解释:

默认配置:如果没有传入 config,代码会默认设置请求头 Content-Type: 'application/json;charset=UTF-8' 和空的查询参数对象 params: {}。这是为了确保请求时使用 JSON 格式并且没有附加查询参数。

发起请求:axios.get() 用来发送 HTTP GET 请求。uri 会与 HOST 拼接成完整的 URL,例如 http://10.176.26.122:8080/some-endpoint。

返回响应数据:使用 await 等待请求完成,获取响应 resp。然后输出响应的 status(HTTP 状态码)和 data(返回的数据),并返回 resp.data,通常是服务器返回的数据。

错误处理:如果请求失败,进入 catch 块,打印错误的状态码和响应数据(error.response.data)。

至于 put 的用法显然是 url + body + config,剩下两个类比一下即可理解,下面是一些点

1.config 的作用

在 Axios 中,config 是一个配置对象,用于指定请求的具体细节,如请求头(headers)、查询参数(params)、请求体(data)等。config 允许你定制每个请求的行为,而不是每次都使用默认的设置。

Get 函数的 config 参数是用来传递额外的请求配置的。如果你没有显式传递 config 参数,那么函数会使用默认的配置。

例如,在你调用 Get 函数时,config 参数可以包括:

请求头(headers):如设置 Content-Type。

查询参数(params):如在 URL 中附加的查询字符串(例如 ?page=1&size=10)。

请求超时(timeout):请求超时的时间(例如 timeout: 1000 表示请求超过 1 秒则自动取消)。

// 调用 Get 函数时传入 config 参数
Get('/users', {
  headers: { 'Authorization': 'Bearer token' },
  params: { page: 1, limit: 10 },
});

在这个例子中,我们给 Get 函数传入了一个包含 headers 和 params 的配置对象:

headers:设置了请求的认证令牌。

params:设置了查询参数,告诉服务器请求第一页的数据,每页显示 10 个用户。

2. 默认配置

如果你没有传递 config 参数,Get 函数会使用函数内部定义的默认配置。

默认配置是函数内部定义的配置项。它主要包括:

headers:默认设置了 Content-Type: 'application/json;charset=UTF-8',表示发送的数据是 JSON 格式。

params:如果没有传入 params,会默认设置为空对象 {},表示没有查询参数。

//这是没有参数时的配置
const defaultConfig = {
  headers: {
    'Content-Type': 'application/json;charset=UTF-8',  // 请求的内容类型为 JSON
  },
  params: {},  // 没有查询参数
};

// 示例一:没有传递 config 参数
Get('/users');

//上面这行相当于下面两行请求
GET http://10.176.26.122:8080/users
Content-Type: application/json;charset=UTF-8

//示例二:传递了自定义的 config 参数
Get('/users', {
  headers: { 'Authorization': 'Bearer token' },
  params: { page: 1, size: 10 },
});

//这时发出的请求就会不同,即
GET http://10.176.26.122:8080/users?page=1&size=10
Authorization: Bearer token
Content-Type: application/json;charset=UTF-8

好了你现在已经学会了 Axios 库的 HTTP 请求编程了,开始写项目吧(这话不是我说的)

3. error 对象的结构(这是题外话)

当请求失败时,catch 捕获到的 error 通常是一个包含多个属性的对象。

I. error.message

作用:message 是一个简单的错误信息,通常描述的是错误的类型或原因。

适用场景:无论请求失败的原因是什么,message 通常都会提供一种对错误的描述。

值的示例:

网络错误时:"Network Error"

请求超时时:"timeout of 1000ms exceeded"

请求被取消时:"Request was canceled"

配置错误时:"Invalid URL"

II. error.response

作用:response 是当服务器成功响应请求时返回的响应对象,它包含了 HTTP 状态码、响应数据等信息。response 只有在 HTTP 请求成功(服务器返回了响应)时才会存在。

包含的字段:

response.status: HTTP 状态码(如 404、500 等)。

response.data: 响应体的内容,通常是服务器返回的具体错误信息。

response.headers: 响应头。

有值时:当请求成功发出并且服务器响应了(即使是错误的状态码如 404、500),error.response 会存在,并且包含 HTTP 状态码、错误信息等。

没有值时:当请求因为网络错误、超时、配置错误等问题没有得到响应时,error.response 不会有值。

III. error.status

作用:在 catch 中,error.status 通常是对 error.response.status 的引用或简化。并不是所有的 Axios 错误都直接暴露 status,尤其是在没有响应的情况下(例如,网络错误或请求超时时)。

何时有值:只有在 error.response 存在的情况下(即请求返回了响应)才会有 status,通常这时候 status 会表示 HTTP 状态码(如 404、500 等)。

2024/12/18

今天太糖了,记录一下

//vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      // 将 /api 开头的请求代理到你的后端服务器
      '/api': {
        target: '这里省略我的ip', // 后端服务器地址
        changeOrigin: true,  // 支持跨域
        ws: true,           // 代理 websockets
      }
    }
  }
})

于是我在 request.js 中就别煞笔似的去写 HOST 了,因为如果我写了 HOST 会因为没有通过 Vite 的代理配置而出现跨域问题 🤮,希望以后别糖

posted @ 2024-11-28 19:52  KJGKMTZB  阅读(82)  评论(0)    收藏  举报