跳到主要内容

Network - HTTP 客户端

network 命名空间提供了一个完整的 HTTP 客户端,支持常见的 HTTP 方法(GET、POST、PUT、DELETE、HEAD 等),并提供灵活的头部管理和响应处理功能。

版本说明

network 命名空间在 SDK v0.3.2 中引入,取代了旧版的 httpClient 命名空间。旧版 httpClient 仍然可用但建议迁移至 network

核心接口

HeaderCollection

HTTP 头部集合管理接口:

interface HeaderCollection {
[key: string]: string; // 索引器访问
Set(key: string, value: string): void;
Get(key: string): string;
Contains(key: string): boolean;
Remove(key: string): boolean;
Clear(): void;
GetKeys(): string[];
GetValues(): string[];
}

RequestMessage

HTTP 请求消息结构:

interface RequestMessage {
url: string; // 请求URL
method: string; // HTTP方法
headers: HeaderCollection; // 请求头部
body?: string; // 请求体(可选)
}

ResponseMessage

HTTP 响应消息结构:

interface ResponseMessage {
status: number; // 状态码
headers: HeaderCollection; // 响应头部
body: string; // 响应体
data?: any; // JSON反序列化对象(可选)
}

方法详解

request()

功能描述:发送自定义 HTTP 请求,支持自定义方法、头部和请求体。

语法

network.request(message: RequestMessage): Promise<ResponseMessage>

参数

  • message:完整的请求参数对象
    • url:请求 URL
    • method:HTTP 方法
    • headers:请求头集合
    • body:请求体(可选)

使用示例

const response = await network.request({
url: "https://api.example.com/data",
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer token123"
},
body: JSON.stringify({ status: "active" })
});

logger.info(`状态码: ${response.status}`);
logger.info(`响应: ${response.body}`);

get()

功能描述:发送 GET 请求。

语法

network.get(url: string): Promise<ResponseMessage>

使用示例

const response = await network.get("https://api.example.com/users");
if (response.status === 200) {
const users = response.data; // 自动JSON反序列化
logger.info(`获取到 ${users.length} 个用户`);
}

post()

功能描述:发送 POST 请求。

语法

network.post(url: string, body: any): Promise<ResponseMessage>

使用示例

const response = await network.post(
"https://api.example.com/users",
JSON.stringify({ name: "张三", email: "zhangsan@example.com" })
);

if (response.status === 201) {
logger.info("用户创建成功");
}

put()

功能描述:发送 PUT 请求。

语法

network.put(url: string, body: any): Promise<ResponseMessage>

del()

功能描述:发送 DELETE 请求。

语法

network.del(url: string): Promise<ResponseMessage>

使用示例

const response = await network.del("https://api.example.com/users/123");
if (response.status === 204) {
logger.info("用户已删除");
}

功能描述:发送 HEAD 请求,仅获取响应头。

语法

network.head(url: string): Promise<ResponseMessage>

HeaderCollection 方法

索引器访问

直接通过 [] 操作符读写头部:

// 设置
headers["Content-Type"] = "application/json";

// 读取
const contentType = headers["Content-Type"];

Set() / Get()

headers.Set("Authorization", "Bearer token123");
const auth = headers.Get("Authorization");

Contains()

检查是否包含指定头部:

if (headers.Contains("X-Custom-Header")) {
logger.info("包含自定义头部");
}

Remove()

移除指定头部:

headers.Remove("X-Unused-Header");

Clear()

清空所有头部:

headers.Clear();

GetKeys() / GetValues()

遍历所有头部:

const keys = headers.GetKeys();
for (let i = 0; i < keys.length; i++) {
logger.info(`${keys[i]}: ${headers.Get(keys[i])}`);
}

实战示例

调用外部 API

async function fetchWeather(city) {
try {
const response = await network.get(
`https://api.weather.com/v1/current?city=${encodeURIComponent(city)}`
);

if (response.status === 200 && response.data) {
return {
temperature: response.data.current.temp,
condition: response.data.current.condition,
humidity: response.data.current.humidity
};
}
} catch (err) {
logger.error(`天气查询失败: ${err}`);
}
return null;
}

bus.on("group_message_event", async (event) => {
if (event.RawMessage.startsWith("/天气 ")) {
const city = event.RawMessage.substring(4).trim();
const weather = await fetchWeather(city);

if (weather) {
event.Context.Reply(new MessageChain().Text(
`${city}天气:${weather.condition},温度${weather.temperature}°C,湿度${weather.humidity}%`
));
} else {
event.Context.Reply(new MessageChain().Text("天气查询失败"));
}
}
});

带重试的请求

async function requestWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await network.request({
url: url,
method: options.method || "GET",
headers: options.headers || {},
body: options.body
});

if (response.status >= 200 && response.status < 300) {
return response;
}

logger.warning(`请求失败 (${response.status}),第 ${i + 1} 次重试...`);
} catch (err) {
logger.error(`请求异常: ${err},第 ${i + 1} 次重试...`);
}

// 等待后重试
await new Promise(resolve => threading.setTimeout(resolve, 1000 * (i + 1)));
}

throw new Error(`请求失败,已重试 ${maxRetries}`);
}

文件上传 (multipart)

async function uploadFile(filePath, uploadUrl) {
const boundary = "----WebKitFormBoundary" + Math.random().toString(36).substring(2);

const fileBytes = archive.readBytes(filePath);
if (!fileBytes) {
logger.error("文件不存在");
return;
}

// 构造 multipart body
const header = `--${boundary}\r\nContent-Disposition: form-data; name="file"; filename="${filePath}"\r\nContent-Type: application/octet-stream\r\n\r\n`;
const footer = `\r\n--${boundary}--\r\n`;

// 注意:multipart 上传需要使用 request() 方法手动构造
const response = await network.request({
url: uploadUrl,
method: "POST",
headers: {
"Content-Type": `multipart/form-data; boundary=${boundary}`
},
body: header + String.fromCharCode.apply(null, fileBytes) + footer
});

return response;
}

错误处理

async function safeRequest(url) {
try {
const response = await network.get(url);

switch (response.status) {
case 200:
return response.data;
case 401:
logger.error("认证失败,请检查API密钥");
return null;
case 404:
logger.error("请求的资源不存在");
return null;
case 429:
logger.warning("请求过于频繁,请稍后重试");
return null;
case 500:
logger.error("服务器内部错误");
return null;
default:
logger.warning(`未知状态码: ${response.status}`);
return null;
}
} catch (err) {
logger.error(`网络请求异常: ${err}`);
return null;
}
}

与旧版 httpClient 的区别

特性httpClient (旧)network (新)
命名空间httpClientnetwork
响应数据bodybody + data(自动JSON解析)
PUT 方法需用 request()内置 put()
DELETE 方法需用 request()内置 del()
HEAD 方法不支持内置 head()

建议新项目使用 network 命名空间,旧版 httpClient 仍可使用但推荐迁移。

遇到麻烦了?

有偿服务

我们提供有偿代安装服务,解决您的环境配置烦恼。

了解详情
Miku

少年,买服务器吗?

持证经营

专注高性价比游戏云VPS,铂金 / I7 / R9 / 物理机

💰 最低六元起、买不了吃亏买不了上当,快来看看吧~

快来看看