v1.1.3: 网络层加固
- gfetch 失败自动重试 2 次(1s 间隔),应对代理/节点瞬断 - 重试耗尽降级原生 fetch(CDN 带 ACAO:* 可直连) - 错误原因完整显示到面板,不再只报网络错误 - 背景: 17:25 mihomo 节点故障导致分片请求全部建连失败, Reqable 记录 remote.ip 为空 + mihomo 17:29 重启为证
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 黄果短剧全集下载
|
// @name 黄果短剧全集下载
|
||||||
// @namespace huangguo-video
|
// @namespace huangguo-video
|
||||||
// @version 1.1.2
|
// @version 1.1.3
|
||||||
// @description 在黄果短剧详情页添加"全集下载"按钮:下载全部集数 → 解密 → 转 MP4 → 打包 ZIP 存到 ~/Downloads,文件名为 剧名_集数
|
// @description 在黄果短剧详情页添加"全集下载"按钮:下载全部集数 → 解密 → 转 MP4 → 打包 ZIP 存到 ~/Downloads,文件名为 剧名_集数
|
||||||
// @author CETACEA
|
// @author CETACEA
|
||||||
// @match https://huangguo.me/detail/*
|
// @match https://huangguo.me/detail/*
|
||||||
@@ -22,7 +22,22 @@
|
|||||||
const CONCURRENCY = 4; // 分片并发下载数
|
const CONCURRENCY = 4; // 分片并发下载数
|
||||||
|
|
||||||
/* ---------- 网络:GM_xmlhttpRequest promise 化(绕 CORS) ---------- */
|
/* ---------- 网络:GM_xmlhttpRequest promise 化(绕 CORS) ---------- */
|
||||||
function gfetch(url, type = 'text') {
|
function gfetch(url, type = 'text', retries = 2) {
|
||||||
|
const fail = (why) => {
|
||||||
|
if (retries > 0) {
|
||||||
|
console.warn(`[全集下载] ${why},1s 后重试(剩 ${retries} 次):`, url);
|
||||||
|
return new Promise((r) => setTimeout(r, 1000))
|
||||||
|
.then(() => gfetch(url, type, retries - 1));
|
||||||
|
}
|
||||||
|
// 重试耗尽 → 降级原生 fetch(CDN 带 Access-Control-Allow-Origin: * 可直连)
|
||||||
|
console.warn(`[全集下载] GM 失败,尝试原生 fetch:`, url);
|
||||||
|
return fetch(url).then((resp) => {
|
||||||
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}: ${url.slice(0, 100)}`);
|
||||||
|
return type === 'arraybuffer' ? resp.arrayBuffer() : resp.text();
|
||||||
|
}).catch((e) => {
|
||||||
|
throw new Error(`${why}(且 fetch 兜底失败:${e.message}): ${url.slice(0, 120)}`);
|
||||||
|
});
|
||||||
|
};
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
GM_xmlhttpRequest({
|
GM_xmlhttpRequest({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
@@ -32,8 +47,8 @@
|
|||||||
onload: (r) => (r.status >= 200 && r.status < 300
|
onload: (r) => (r.status >= 200 && r.status < 300
|
||||||
? resolve(type === 'arraybuffer' ? r.response : r.responseText)
|
? resolve(type === 'arraybuffer' ? r.response : r.responseText)
|
||||||
: reject(new Error(`HTTP ${r.status}: ${url.slice(0, 100)}`))),
|
: reject(new Error(`HTTP ${r.status}: ${url.slice(0, 100)}`))),
|
||||||
onerror: () => reject(new Error(`网络错误: ${url.slice(0, 100)}`)),
|
onerror: () => fail(`网络错误`).then(resolve, reject),
|
||||||
ontimeout: () => reject(new Error(`超时: ${url.slice(0, 100)}`)),
|
ontimeout: () => fail(`超时30s`).then(resolve, reject),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user