- monitor-server.js: Cookie存储改为Map合并机制,避免丢失CDN Cookie导致403 - checkActivity.js: 补上Cookie两步请求逻辑,修复无Cookie直接请求失败的问题 - public/index.html: 新增20秒刷新间隔选项
99 lines
3.5 KiB
JavaScript
99 lines
3.5 KiB
JavaScript
const express = require('express');
|
||
const cors = require('cors');
|
||
const path = require('path');
|
||
|
||
const app = express();
|
||
const PORT = 3000;
|
||
|
||
app.use(cors());
|
||
app.use(express.static(path.join(__dirname, 'public')));
|
||
|
||
const ACTIVITY_URL = 'https://www.szhdy.com/activities/default.html?method=activity&id=9';
|
||
const REQUEST_HEADERS = {
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
|
||
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
||
'Connection': 'keep-alive',
|
||
'Upgrade-Insecure-Requests': '1',
|
||
};
|
||
|
||
// 存储 Cookie(key-value Map,支持合并更新)
|
||
let cookieJar = new Map();
|
||
let cookieExpiry = 0;
|
||
|
||
// 从 set-cookie 响应头提取 Cookie,合并到 cookieJar
|
||
function mergeCookies(response) {
|
||
const setCookieHeaders = response.headers.getSetCookie?.() || [];
|
||
for (const header of setCookieHeaders) {
|
||
const pair = header.split(';')[0]; // 取 name=value 部分
|
||
const eqIdx = pair.indexOf('=');
|
||
if (eqIdx > 0) {
|
||
const name = pair.substring(0, eqIdx).trim();
|
||
const value = pair.substring(eqIdx + 1).trim();
|
||
cookieJar.set(name, value);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 将 cookieJar 序列化为请求头格式
|
||
function getCookieString() {
|
||
return Array.from(cookieJar.entries()).map(([k, v]) => `${k}=${v}`).join('; ');
|
||
}
|
||
|
||
// 获取有效 Cookie(过期或为空时重新获取)
|
||
async function getValidCookies() {
|
||
if (cookieJar.size > 0 && Date.now() < cookieExpiry) {
|
||
return getCookieString();
|
||
}
|
||
|
||
console.log('[Cookie] 正在获取新的 Cookie...');
|
||
cookieJar.clear();
|
||
const response = await fetch(ACTIVITY_URL, { headers: REQUEST_HEADERS, redirect: 'manual' });
|
||
mergeCookies(response);
|
||
// CDN Cookie 有效期 2 小时,保守取 1 小时刷新
|
||
cookieExpiry = Date.now() + 3600 * 1000;
|
||
console.log('[Cookie] 获取成功:', getCookieString());
|
||
return getCookieString();
|
||
}
|
||
|
||
app.get('/api/activity', async (req, res) => {
|
||
try {
|
||
const cookies = await getValidCookies();
|
||
const response = await fetch(ACTIVITY_URL, {
|
||
headers: {
|
||
...REQUEST_HEADERS,
|
||
'Cookie': cookies,
|
||
}
|
||
});
|
||
|
||
const html = await response.text();
|
||
// 合并第二次请求返回的 Cookie(如 PHPSESSID)
|
||
mergeCookies(response);
|
||
|
||
// 如果返回内容过短,可能 Cookie 失效,清除缓存并重试一次
|
||
if (html.length < 1000) {
|
||
console.log('[Cookie] 响应内容过短,尝试刷新 Cookie 重试...');
|
||
cookieJar.clear();
|
||
cookieExpiry = 0;
|
||
const newCookies = await getValidCookies();
|
||
const retryResponse = await fetch(ACTIVITY_URL, {
|
||
headers: {
|
||
...REQUEST_HEADERS,
|
||
'Cookie': newCookies,
|
||
}
|
||
});
|
||
const retryHtml = await retryResponse.text();
|
||
mergeCookies(retryResponse);
|
||
return res.json({ success: true, html: retryHtml });
|
||
}
|
||
|
||
res.json({ success: true, html });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, error: error.message });
|
||
}
|
||
});
|
||
|
||
app.listen(PORT, () => {
|
||
console.log(`活动监控服务已启动: http://localhost:${PORT}`);
|
||
});
|