基于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 的代理配置而出现跨域问题 🤮,希望以后别糖