mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-04-18 04:07:26 +00:00
(jsrt) chore: docs
This commit is contained in:
@@ -71,90 +71,147 @@ var result = db.Exec("UPDATE users SET last_login = NOW() WHERE id = ?", 123);
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 请求限流
|
||||
```js
|
||||
// 例子:基于数据库的速率限制
|
||||
if (req.url.includes("/v1/chat/completions")) {
|
||||
try {
|
||||
// Check recent requests from this IP
|
||||
var recentRequests = db.query(
|
||||
"SELECT COUNT(*) as count FROM logs WHERE created_at > ? AND ip = ?",
|
||||
Math.floor(Date.now() / 1000) - 60, // last minute
|
||||
req.remoteIP
|
||||
);
|
||||
if (recentRequests && recentRequests.length > 0 && recentRequests[0].count > 10) {
|
||||
console.log("速率限制 IP:", req.remoteIP);
|
||||
return {
|
||||
block: true,
|
||||
statusCode: 429,
|
||||
message: "超过速率限制"
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Ratelimit 数据库错误:", e);
|
||||
}
|
||||
}
|
||||
|
||||
```javascript
|
||||
function preProcessRequest(ctx) {
|
||||
// 基于 IP 的简单限流
|
||||
var recentRequests = db.Query(
|
||||
"SELECT COUNT(*) as count FROM request_logs WHERE ip = ? AND timestamp > ?",
|
||||
ctx.remoteIP,
|
||||
new Date(Date.now() - 60000).toISOString() // 最近1分钟
|
||||
);
|
||||
|
||||
if (recentRequests[0].count > 100) {
|
||||
return {
|
||||
block: true,
|
||||
statusCode: 429,
|
||||
message: "Too many requests"
|
||||
|
||||
// 例子:修改请求
|
||||
if (req.url.includes("/chat/completions")) {
|
||||
try {
|
||||
var bodyObj = req.body;
|
||||
let firstMsg = { // 需要新建一个对象,不能修改原有对象
|
||||
role: "user",
|
||||
content: "喵呜🐱~嘻嘻"
|
||||
};
|
||||
}
|
||||
|
||||
// 记录请求
|
||||
db.Exec(
|
||||
"INSERT INTO request_logs (ip, url, timestamp) VALUES (?, ?, ?)",
|
||||
ctx.remoteIP, ctx.url, new Date().toISOString()
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 请求修改
|
||||
|
||||
```javascript
|
||||
function preProcessRequest(ctx) {
|
||||
if (ctx.method === "POST" && ctx.body) {
|
||||
try {
|
||||
var bodyObj = JSON.parse(ctx.body);
|
||||
|
||||
// 添加默认参数
|
||||
if (!bodyObj.temperature) {
|
||||
bodyObj.temperature = 0.7;
|
||||
bodyObj.messages[0] = firstMsg;
|
||||
console.log("Modified first message:", JSON.stringify(firstMsg));
|
||||
console.log("Modified body:", JSON.stringify(bodyObj));
|
||||
return {
|
||||
body: bodyObj,
|
||||
headers: {
|
||||
...req.headers,
|
||||
"X-Modified-Body": "true"
|
||||
}
|
||||
|
||||
// 添加用户标识
|
||||
bodyObj._userId = ctx.extra.userId;
|
||||
|
||||
return {
|
||||
body: JSON.stringify(bodyObj)
|
||||
};
|
||||
} catch (e) {
|
||||
console.error("Failed to parse request body:", e);
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
console.error("Failed to modify request body:", {
|
||||
message: e.message,
|
||||
stack: e.stack,
|
||||
bodyType: typeof req.body,
|
||||
url: req.url
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 响应增强
|
||||
|
||||
```javascript
|
||||
function postProcessResponse(ctx, response) {
|
||||
if (response.statusCode === 200 && ctx.url.includes("/v1/chat/completions")) {
|
||||
try {
|
||||
var bodyObj = JSON.parse(response.body);
|
||||
|
||||
// 添加自定义元数据
|
||||
bodyObj.metadata = {
|
||||
processedAt: new Date().toISOString(),
|
||||
version: "1.0.0"
|
||||
};
|
||||
|
||||
// 记录成功的对话
|
||||
db.Exec(
|
||||
"INSERT INTO chat_logs (user_ip, model, tokens, timestamp) VALUES (?, ?, ?, ?)",
|
||||
ctx.remoteIP, bodyObj.model, bodyObj.usage?.total_tokens || 0, new Date().toISOString()
|
||||
);
|
||||
|
||||
return {
|
||||
statusCode: response.statusCode,
|
||||
headers: response.headers,
|
||||
body: JSON.stringify(bodyObj)
|
||||
};
|
||||
} catch (e) {
|
||||
console.error("Failed to process chat completion response:", e);
|
||||
}
|
||||
// 例子:读取最近一条日志,新增 jsrt 日志,并输出日志总数
|
||||
try {
|
||||
// 1. 读取最近一条日志
|
||||
var recentLogs = logdb.query(
|
||||
"SELECT id, user_id, username, content, created_at FROM logs ORDER BY id DESC LIMIT 1"
|
||||
);
|
||||
var recentLog = null;
|
||||
if (recentLogs && recentLogs.length > 0) {
|
||||
recentLog = recentLogs[0];
|
||||
console.log("最近一条日志:", JSON.stringify(recentLog));
|
||||
}
|
||||
// 2. 新增一条 jsrt 日志
|
||||
var currentTimestamp = Math.floor(Date.now() / 1000);
|
||||
var jsrtLogContent = "JSRT 预处理中间件执行 - " + req.URL + " - " + new Date().toISOString();
|
||||
var insertResult = logdb.exec(
|
||||
"INSERT INTO logs (user_id, username, created_at, type, content) VALUES (?, ?, ?, ?, ?)",
|
||||
req.UserID || 0,
|
||||
req.Username || "jsrt-system",
|
||||
currentTimestamp,
|
||||
4, // LogTypeSystem
|
||||
jsrtLogContent
|
||||
);
|
||||
if (insertResult.error) {
|
||||
console.error("插入 JSRT 日志失败:", insertResult.error);
|
||||
} else {
|
||||
console.log("成功插入 JSRT 日志,影响行数:", insertResult.rowsAffected);
|
||||
}
|
||||
// 3. 输出日志总数
|
||||
var totalLogsResult = logdb.query("SELECT COUNT(*) as total FROM logs");
|
||||
var totalLogs = 0;
|
||||
if (totalLogsResult && totalLogsResult.length > 0) {
|
||||
totalLogs = totalLogsResult[0].total;
|
||||
}
|
||||
console.log("当前日志总数:", totalLogs);
|
||||
console.log("JSRT 日志管理示例执行完成");
|
||||
} catch (e) {
|
||||
console.error("JSRT 日志管理示例执行失败:", {
|
||||
message: e.message,
|
||||
stack: e.stack,
|
||||
url: req.URL
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 例子:使用 fetch 调用外部 API
|
||||
if (req.url.includes("/api/uptime/status")) {
|
||||
try {
|
||||
// 使用 httpbin.org/ip 测试 fetch 功能
|
||||
var response = fetch("https://httpbin.org/ip", {
|
||||
method: "GET",
|
||||
timeout: 5, // 5秒超时
|
||||
headers: {
|
||||
"User-Agent": "OneAPI-JSRT/1.0"
|
||||
}
|
||||
});
|
||||
if (response.Error.length === 0) {
|
||||
// 解析响应体
|
||||
var ipData = JSON.parse(response.Body);
|
||||
// 可以根据获取到的 IP 信息进行后续处理
|
||||
if (ipData.origin) {
|
||||
console.log("外部 IP 地址:", ipData.origin);
|
||||
// 示例:记录 IP 信息到数据库
|
||||
var currentTimestamp = Math.floor(Date.now() / 1000);
|
||||
var logContent = "Fetch 示例 - 外部 IP: " + ipData.origin + " - " + new Date().toISOString();
|
||||
var insertResult = logdb.exec(
|
||||
"INSERT INTO logs (user_id, username, created_at, type, content) VALUES (?, ?, ?, ?, ?)",
|
||||
0,
|
||||
"jsrt-fetch",
|
||||
currentTimestamp,
|
||||
4, // LogTypeSystem
|
||||
logContent
|
||||
);
|
||||
if (insertResult.error) {
|
||||
console.error("记录 IP 信息失败:", insertResult.error);
|
||||
} else {
|
||||
console.log("成功记录 IP 信息到数据库");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error("Fetch 失败 ", response.Status, " ", response.Error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Fetch 失败:", {
|
||||
message: e.message,
|
||||
stack: e.stack,
|
||||
url: req.url
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user