feat: api fetch timeout

This commit is contained in:
Gabe
2025-07-01 12:38:06 +08:00
parent 30129abef3
commit 97b4935bc4
4 changed files with 64 additions and 21 deletions

View File

@@ -40,7 +40,12 @@ export const CLIENT_EDGE = "edge";
export const CLIENT_FIREFOX = "firefox";
export const CLIENT_USERSCRIPT = "userscript";
export const CLIENT_THUNDERBIRD = "thunderbird";
export const CLIENT_EXTS = [CLIENT_CHROME, CLIENT_EDGE, CLIENT_FIREFOX, CLIENT_THUNDERBIRD];
export const CLIENT_EXTS = [
CLIENT_CHROME,
CLIENT_EDGE,
CLIENT_FIREFOX,
CLIENT_THUNDERBIRD,
];
export const KV_RULES_KEY = "kiss-rules.json";
export const KV_WORDS_KEY = "kiss-words.json";
@@ -101,7 +106,8 @@ export const URL_BAIDU_TRANSAPI = "https://fanyi.baidu.com/transapi";
export const URL_BAIDU_TRANSAPI_V2 = "https://fanyi.baidu.com/v2transapi";
export const URL_DEEPLFREE_TRAN = "https://www2.deepl.com/jsonrpc";
export const URL_TENCENT_TRANSMART = "https://transmart.qq.com/api/imt";
export const URL_VOLCENGINE_TRAN = "https://translate.volcengine.com/crx/translate/v1";
export const URL_VOLCENGINE_TRAN =
"https://translate.volcengine.com/crx/translate/v1";
export const URL_NIUTRANS_REG =
"https://niutrans.com/login?active=3&userSource=kiss-translator";
@@ -530,6 +536,8 @@ export const DEFAULT_SUBRULES_LIST = [
},
];
export const DEFAULT_HTTP_TIMEOUT = 5000; // 调用超时时间
// 翻译接口
const defaultCustomApi = {
url: "",
@@ -539,6 +547,9 @@ const defaultCustomApi = {
resHook: "", // response 钩子函数
fetchLimit: DEFAULT_FETCH_LIMIT,
fetchInterval: DEFAULT_FETCH_INTERVAL,
apiName: "",
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
};
const defaultOpenaiApi = {
url: "https://api.openai.com/v1/chat/completions",
@@ -552,6 +563,7 @@ const defaultOpenaiApi = {
fetchInterval: 500,
apiName: "",
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT * 2,
};
const defaultOllamaApi = {
url: "http://localhost:11434/api/generate",
@@ -559,12 +571,13 @@ const defaultOllamaApi = {
model: "llama3.1",
systemPrompt: `You are a professional, authentic machine translation engine.`,
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
think:false,
thinkIgnore:`qwen3,deepseek-r1`,
think: false,
thinkIgnore: `qwen3,deepseek-r1`,
fetchLimit: 1,
fetchInterval: 500,
apiName: "",
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT * 2,
};
export const DEFAULT_TRANS_APIS = {
[OPT_TRANS_GOOGLE]: {
@@ -572,8 +585,9 @@ export const DEFAULT_TRANS_APIS = {
key: "",
fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量
fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间
apiName: OPT_TRANS_GOOGLE,
isDisabled: false,
apiName: OPT_TRANS_GOOGLE, // 接口自定义名称
isDisabled: false, // 是否禁用
httpTimeout: DEFAULT_HTTP_TIMEOUT, // 超时时间
},
[OPT_TRANS_GOOGLE2]: {
url: URL_GOOGLE_TRAN2,
@@ -582,30 +596,35 @@ export const DEFAULT_TRANS_APIS = {
fetchInterval: DEFAULT_FETCH_INTERVAL,
apiName: OPT_TRANS_GOOGLE2,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_MICROSOFT]: {
fetchLimit: DEFAULT_FETCH_LIMIT,
fetchInterval: DEFAULT_FETCH_INTERVAL,
apiName: OPT_TRANS_MICROSOFT,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_BAIDU]: {
fetchLimit: DEFAULT_FETCH_LIMIT,
fetchInterval: DEFAULT_FETCH_INTERVAL,
apiName: OPT_TRANS_BAIDU,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_TENCENT]: {
fetchLimit: DEFAULT_FETCH_LIMIT,
fetchInterval: DEFAULT_FETCH_INTERVAL,
apiName: OPT_TRANS_TENCENT,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_VOLCENGINE]: {
fetchLimit: DEFAULT_FETCH_LIMIT,
fetchInterval: DEFAULT_FETCH_INTERVAL,
apiName: OPT_TRANS_VOLCENGINE,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_DEEPL]: {
url: "https://api-free.deepl.com/v2/translate",
@@ -614,12 +633,14 @@ export const DEFAULT_TRANS_APIS = {
fetchInterval: 500,
apiName: OPT_TRANS_DEEPL,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_DEEPLFREE]: {
fetchLimit: 1,
fetchInterval: 500,
apiName: OPT_TRANS_DEEPLFREE,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_DEEPLX]: {
url: "http://localhost:1188/translate",
@@ -628,6 +649,7 @@ export const DEFAULT_TRANS_APIS = {
fetchInterval: 500,
apiName: OPT_TRANS_DEEPLX,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_NIUTRANS]: {
url: "https://api.niutrans.com/NiuTransServer/translation",
@@ -638,6 +660,7 @@ export const DEFAULT_TRANS_APIS = {
fetchInterval: DEFAULT_FETCH_INTERVAL,
apiName: OPT_TRANS_NIUTRANS,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
},
[OPT_TRANS_OPENAI]: defaultOpenaiApi,
[OPT_TRANS_OPENAI_2]: defaultOpenaiApi,
@@ -652,6 +675,7 @@ export const DEFAULT_TRANS_APIS = {
fetchInterval: 500,
apiName: OPT_TRANS_GEMINI,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT * 2,
},
[OPT_TRANS_CLAUDE]: {
url: "https://api.anthropic.com/v1/messages",
@@ -665,6 +689,7 @@ export const DEFAULT_TRANS_APIS = {
fetchInterval: 500,
apiName: OPT_TRANS_CLAUDE,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT * 2,
},
[OPT_TRANS_CLOUDFLAREAI]: {
url: "https://api.cloudflare.com/client/v4/accounts/{{ACCOUNT_ID}}/ai/run/@cf/meta/m2m100-1.2b",
@@ -673,6 +698,7 @@ export const DEFAULT_TRANS_APIS = {
fetchInterval: 500,
apiName: OPT_TRANS_CLOUDFLAREAI,
isDisabled: false,
httpTimeout: DEFAULT_HTTP_TIMEOUT * 2,
},
[OPT_TRANS_OLLAMA]: defaultOllamaApi,
[OPT_TRANS_OLLAMA_2]: defaultOllamaApi,
@@ -699,7 +725,6 @@ export const DEFAULT_SHORTCUTS = {
export const TRANS_MIN_LENGTH = 5; // 最短翻译长度
export const TRANS_MAX_LENGTH = 5000; // 最长翻译长度
export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数
export const HTTP_TIMEOUT = 5000; // 调用超时时间
export const DEFAULT_BLACKLIST = [
"https://fishjar.github.io/kiss-translator/options.html",
"https://translate.google.com",
@@ -717,7 +742,7 @@ export const DEFAULT_SETTING = {
minLength: TRANS_MIN_LENGTH,
maxLength: TRANS_MAX_LENGTH,
newlineLength: TRANS_NEWLINE_LENGTH,
httpTimeout: HTTP_TIMEOUT,
httpTimeout: DEFAULT_HTTP_TIMEOUT,
clearCache: false, // 是否在浏览器下次启动时清除缓存
injectRules: true, // 是否注入订阅规则
// injectWebfix: true, // 是否注入修复补丁(作废)

View File

@@ -9,7 +9,7 @@ import {
CACHE_NAME,
DEFAULT_FETCH_INTERVAL,
DEFAULT_FETCH_LIMIT,
HTTP_TIMEOUT,
DEFAULT_HTTP_TIMEOUT,
} from "../config";
import { isBg } from "./browser";
import { genTransReq } from "../apis/trans";
@@ -40,7 +40,10 @@ const newCacheReq = async (input, init) => {
* @param {*} init
* @returns
*/
export const fetchGM = async (input, { method = "GET", headers, body, timeout = HTTP_TIMEOUT } = {}) =>
export const fetchGM = async (
input,
{ method = "GET", headers, body, timeout } = {}
) =>
new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method,
@@ -82,13 +85,14 @@ export const fetchPatcher = async (input, init, transOpts, apiSetting) => {
throw new Error("url is empty");
}
let timeout = HTTP_TIMEOUT;
let timeout = apiSetting?.httpTimeout || DEFAULT_HTTP_TIMEOUT;
if (!apiSetting) {
try {
// todo: 不必每次都查询,缓存参数
timeout = (await getSettingWithDefault()).httpTimeout;
} catch (err) {
//
}
}
if (isGm) {
let info;

View File

@@ -29,6 +29,7 @@ import {
URL_NIUTRANS_REG,
DEFAULT_FETCH_LIMIT,
DEFAULT_FETCH_INTERVAL,
DEFAULT_HTTP_TIMEOUT,
} from "../../config";
import { useState } from "react";
import { useI18n } from "../../hooks/I18n";
@@ -125,6 +126,7 @@ function ApiFields({ translator }) {
thinkIgnore = "",
fetchLimit = DEFAULT_FETCH_LIMIT,
fetchInterval = DEFAULT_FETCH_INTERVAL,
httpTimeout = DEFAULT_HTTP_TIMEOUT,
dictNo = "",
memoryNo = "",
reqHook = "",
@@ -144,6 +146,9 @@ function ApiFields({ translator }) {
case "fetchInterval":
value = limitNumber(value, 0, 5000);
break;
case "httpTimeout":
value = limitNumber(value, 5000, 30000);
break;
case "temperature":
value = limitFloat(value, 0, 2);
break;
@@ -263,7 +268,7 @@ function ApiFields({ translator }) {
</>
)}
{(translator.startsWith(OPT_TRANS_OLLAMA)) && (
{translator.startsWith(OPT_TRANS_OLLAMA) && (
<>
<TextField
select
@@ -368,13 +373,22 @@ function ApiFields({ translator }) {
onChange={handleChange}
/>
<TextField
size="small"
label={i18n("http_timeout")}
type="number"
name="httpTimeout"
defaultValue={httpTimeout}
onChange={handleChange}
/>
<FormControlLabel
control={
<Switch
size="small"
name="isDisabled"
checked={isDisabled}
onChange={()=>{
onChange={() => {
updateApi({ isDisabled: !isDisabled });
}}
/>

View File

@@ -27,7 +27,7 @@ import {
DEFAULT_CSPLIST,
MSG_CONTEXT_MENUS,
MSG_UPDATE_CSP,
HTTP_TIMEOUT,
DEFAULT_HTTP_TIMEOUT,
} from "../../config";
import { useShortcut } from "../../hooks/Shortcut";
import ShortcutInput from "./ShortcutInput";
@@ -114,7 +114,7 @@ export default function Settings() {
maxLength,
clearCache,
newlineLength = TRANS_NEWLINE_LENGTH,
httpTimeout = HTTP_TIMEOUT,
httpTimeout = DEFAULT_HTTP_TIMEOUT,
contextMenuType = 1,
touchTranslate = 2,
blacklist = DEFAULT_BLACKLIST.join(",\n"),