diff --git a/huangguo_video_dl.user.js b/huangguo_video_dl.user.js index d70ac1a..cf6ee1e 100644 --- a/huangguo_video_dl.user.js +++ b/huangguo_video_dl.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name 黄果短剧全集下载 // @namespace huangguo-video -// @version 1.1.2 +// @version 1.1.3 // @description 在黄果短剧详情页添加"全集下载"按钮:下载全部集数 → 解密 → 转 MP4 → 打包 ZIP 存到 ~/Downloads,文件名为 剧名_集数 // @author CETACEA // @match https://huangguo.me/detail/* @@ -22,7 +22,22 @@ const CONCURRENCY = 4; // 分片并发下载数 /* ---------- 网络: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) => { GM_xmlhttpRequest({ method: 'GET', @@ -32,8 +47,8 @@ onload: (r) => (r.status >= 200 && r.status < 300 ? resolve(type === 'arraybuffer' ? r.response : r.responseText) : reject(new Error(`HTTP ${r.status}: ${url.slice(0, 100)}`))), - onerror: () => reject(new Error(`网络错误: ${url.slice(0, 100)}`)), - ontimeout: () => reject(new Error(`超时: ${url.slice(0, 100)}`)), + onerror: () => fail(`网络错误`).then(resolve, reject), + ontimeout: () => fail(`超时30s`).then(resolve, reject), }); }); }