添加whatshub工单

This commit is contained in:
root
2026-06-20 04:47:34 +08:00
parent a6c87e8e25
commit d5a0ffa6db
271 changed files with 9377 additions and 303 deletions
+73
View File
@@ -0,0 +1,73 @@
/**
* URL 重定向解析:在浏览器导航前尽可能解析 HTTP 级重定向链。
*/
'use strict';
const http = require('http');
const https = require('https');
const REDIRECT_STATUS = new Set([301, 302, 303, 307, 308]);
/**
* 发起单次 HEAD/GET,不自动跟随重定向。
*/
function fetchOnce(method, url, timeoutMs) {
return new Promise((resolve, reject) => {
const parsed = new URL(url);
const lib = parsed.protocol === 'https:' ? https : http;
const req = lib.request(
url,
{ method, timeout: timeoutMs, headers: { 'User-Agent': 'Mozilla/5.0 (compatible; puppeteer-api/1.0)' } },
(res) => {
res.resume();
resolve({ statusCode: res.statusCode || 0, headers: res.headers || {} });
}
);
req.on('timeout', () => {
req.destroy();
reject(new Error('REDIRECT_TIMEOUT'));
});
req.on('error', reject);
req.end();
});
}
/**
* 跟随 HTTP 重定向,返回最终 URL(无法解析时返回原始 URL)。
*/
async function resolveHttpRedirects(startUrl, { maxRedirects = 10, timeoutMs = 12000 } = {}) {
let current = startUrl;
for (let i = 0; i < maxRedirects; i++) {
let response;
try {
response = await fetchOnce('HEAD', current, timeoutMs);
} catch (_) {
response = await fetchOnce('GET', current, timeoutMs);
}
if (!REDIRECT_STATUS.has(response.statusCode)) {
return current;
}
const location = response.headers.location;
if (!location) {
return current;
}
current = new URL(location, current).href;
}
return current;
}
/**
* 从分享页 URL 提取 token 参数(星河等云控)。
*/
function extractShareTokenFromUrl(pageUrl) {
try {
return new URL(pageUrl).searchParams.get('token') || '';
} catch (_) {
return '';
}
}
module.exports = {
resolveHttpRedirects,
extractShareTokenFromUrl,
};