Skip to content

Commit 9e3518d

Browse files
author
Taois
committed
fix:修复嗅探失败问题及嗅探过程软件崩溃问题
1 parent 2efaa0e commit 9e3518d

File tree

1 file changed

+103
-18
lines changed

1 file changed

+103
-18
lines changed

sniffer.cjs

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,33 @@ class Sniffer {
4242
}
4343
}
4444

45+
/**
46+
* 安全的 page.evaluate 调用,处理执行上下文销毁的情况
47+
*/
48+
async safeEvaluate(page, pageFunction, ...args) {
49+
try {
50+
// 检查页面是否已关闭
51+
if (page.isClosed()) {
52+
this.log('页面已关闭,跳过 evaluate 调用');
53+
return null;
54+
}
55+
56+
return await page.evaluate(pageFunction, ...args);
57+
} catch (error) {
58+
// 处理执行上下文销毁错误
59+
if (error.message.includes('Execution context was destroyed') ||
60+
error.message.includes('Cannot find context') ||
61+
error.message.includes('Target closed')) {
62+
this.log('执行上下文已销毁,安全跳过 evaluate 调用:', error.message);
63+
return null;
64+
}
65+
66+
// 其他错误继续抛出
67+
this.log('evaluate 调用发生错误:', error.message);
68+
throw error;
69+
}
70+
}
71+
4572
/**
4673
* 检查是否可以进行 HEAD 请求
4774
*/
@@ -363,7 +390,7 @@ class Sniffer {
363390
// 执行页面脚本
364391
if (script) {
365392
try {
366-
await page.evaluate(script);
393+
await this.safeEvaluate(page, script);
367394
this.log(`网页加载完成后成功执行脚本: ${script}`);
368395
} catch (e) {
369396
this.log(`网页加载完成后执行脚本发生错误: ${e.message}`);
@@ -403,6 +430,11 @@ class Sniffer {
403430
const headUrls = []; // 已经 head 请求过的链接
404431
const page = await this.getPage(headers);
405432

433+
// 外部变量保存嗅探结果,避免依赖页面上下文
434+
let externalRealUrl = '';
435+
let externalRealHeaders = {};
436+
let sniffingSuccess = false;
437+
406438
let actualTimeout = timeout || this.timeout;
407439
if (mode === 1) {
408440
actualTimeout = Math.min(actualTimeout, this.timeout);
@@ -412,12 +444,19 @@ class Sniffer {
412444

413445
// 请求拦截器
414446
const onRequest = async (request) => {
415-
const url = request.url();
416-
const method = request.method();
417-
const requestHeaders = request.headers();
418-
const resourceType = request.resourceType();
419-
420-
this.log('on_request:', url, ' method:', method, ' resource_type:', resourceType);
447+
try {
448+
// 检查页面是否已关闭
449+
if (page.isClosed()) {
450+
this.log('页面已关闭,跳过请求处理');
451+
return false;
452+
}
453+
454+
const url = request.url();
455+
const method = request.method();
456+
const requestHeaders = request.headers();
457+
const resourceType = request.resourceType();
458+
459+
this.log('on_request:', url, ' method:', method, ' resource_type:', resourceType);
421460

422461
// 检查排除正则
423462
if (snifferExclude && new RegExp(snifferExclude, 'mi').test(url)) {
@@ -432,7 +471,13 @@ class Sniffer {
432471

433472
realUrls.push({ url, headers: _headers });
434473

435-
await page.evaluate(([url, _headers, realUrls]) => {
474+
// 保存到外部变量
475+
externalRealUrl = url;
476+
externalRealHeaders = _headers;
477+
sniffingSuccess = true;
478+
479+
// 尝试设置页面变量(可能失败但不影响结果)
480+
await this.safeEvaluate(page, ([url, _headers, realUrls]) => {
436481
window.realUrl = url;
437482
window.realHeaders = _headers;
438483
window.realUrls = realUrls;
@@ -457,7 +502,13 @@ class Sniffer {
457502

458503
realUrls.push({ url, headers: _headers });
459504

460-
await page.evaluate(([url, _headers, realUrls]) => {
505+
// 保存到外部变量
506+
externalRealUrl = url;
507+
externalRealHeaders = _headers;
508+
sniffingSuccess = true;
509+
510+
// 尝试设置页面变量(可能失败但不影响结果)
511+
await this.safeEvaluate(page, ([url, _headers, realUrls]) => {
461512
window.realUrl = url;
462513
window.realHeaders = _headers;
463514
window.realUrls = realUrls;
@@ -501,7 +552,13 @@ class Sniffer {
501552

502553
realUrls.push({ url, headers: _headers });
503554

504-
await page.evaluate(([url, _headers, realUrls]) => {
555+
// 保存到外部变量
556+
externalRealUrl = url;
557+
externalRealHeaders = _headers;
558+
sniffingSuccess = true;
559+
560+
// 尝试设置页面变量(可能失败但不影响结果)
561+
await this.safeEvaluate(page, ([url, _headers, realUrls]) => {
505562
window.realUrl = url;
506563
window.realHeaders = _headers;
507564
window.realUrls = realUrls;
@@ -526,6 +583,19 @@ class Sniffer {
526583
}
527584

528585
return false;
586+
} catch (error) {
587+
// 全局错误处理
588+
if (error.message.includes('Execution context was destroyed') ||
589+
error.message.includes('Cannot find context') ||
590+
error.message.includes('Target closed') ||
591+
error.message.includes('Page closed')) {
592+
this.log('请求处理过程中页面上下文已销毁,安全跳过:', error.message);
593+
return false;
594+
}
595+
596+
this.log('请求处理过程中发生错误:', error.message);
597+
return false;
598+
}
529599
};
530600

531601
// 监听请求
@@ -539,7 +609,7 @@ class Sniffer {
539609
await page.exposeFunction('log', (...args) => console.log(...args));
540610

541611
// 初始化页面变量
542-
await page.evaluate(() => {
612+
await this.safeEvaluate(page, () => {
543613
window.realUrl = '';
544614
window.realHeaders = {};
545615
window.realUrls = [];
@@ -598,7 +668,7 @@ class Sniffer {
598668
`;
599669

600670
await page.evaluateOnNewDocument(jsCode);
601-
await page.evaluate(jsCode);
671+
await this.safeEvaluate(page, jsCode);
602672
this.log(`网页加载完成后成功执行脚本: ${script}`);
603673
} catch (e) {
604674
this.log(`网页加载完成后执行脚本发生错误: ${e.message}`);
@@ -610,10 +680,18 @@ class Sniffer {
610680
// 等待结果
611681
if (mode === 0) {
612682
try {
613-
await page.waitForFunction(() => window.realUrl, { timeout: actualTimeout });
683+
// 优先检查外部变量,如果已经有结果就不需要等待
684+
if (!sniffingSuccess) {
685+
await page.waitForFunction(() => window.realUrl, { timeout: actualTimeout });
686+
} else {
687+
this.log('外部变量已有嗅探结果,跳过等待');
688+
}
614689
} catch (e) {
615690
this.log(`page.waitForFunction window.realUrl 发生了错误: ${e.message}`);
616-
isTimeout = true;
691+
// 即使等待失败,也检查外部变量是否有结果
692+
if (!sniffingSuccess) {
693+
isTimeout = true;
694+
}
617695
}
618696
} else if (mode === 1) {
619697
try {
@@ -624,10 +702,17 @@ class Sniffer {
624702
}
625703
}
626704

627-
// 获取结果
628-
const realUrl = await page.evaluate(() => window.realUrl);
629-
const realHeaders = await page.evaluate(() => window.realHeaders);
630-
const realUrlsResult = await page.evaluate(() => window.realUrls);
705+
// 获取结果 - 优先使用外部变量
706+
let realUrl = externalRealUrl || '';
707+
let realHeaders = externalRealHeaders || {};
708+
let realUrlsResult = realUrls || [];
709+
710+
// 如果外部变量没有结果,再尝试从页面获取
711+
if (!realUrl) {
712+
realUrl = await this.safeEvaluate(page, () => window.realUrl) || '';
713+
realHeaders = await this.safeEvaluate(page, () => window.realHeaders) || {};
714+
realUrlsResult = await this.safeEvaluate(page, () => window.realUrls) || [];
715+
}
631716

632717
const cost = Date.now() - startTime;
633718
const costStr = `${cost} ms`;

0 commit comments

Comments
 (0)