@skrillex1224/playwright-toolkit 2.0.92 → 2.0.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1200,8 +1200,8 @@ var Sse = {
1200
1200
  }
1201
1201
  };
1202
1202
 
1203
- // src/blocking.js
1204
- var logger9 = createLogger("Blocking");
1203
+ // src/interception.js
1204
+ var logger9 = createLogger("Interception");
1205
1205
  var ARCHIVE_EXTENSIONS = [".7z", ".zip", ".rar", ".gz", ".bz2", ".tar", ".zst"];
1206
1206
  var EXECUTABLE_EXTENSIONS = [".exe", ".apk", ".bin", ".dmg", ".jar", ".class"];
1207
1207
  var DOCUMENT_EXTENSIONS = [".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".csv"];
@@ -1248,20 +1248,11 @@ var DEFAULT_BLOCKING_CONFIG = {
1248
1248
  /** 额外自定义扩展名列表 */
1249
1249
  customExtensions: []
1250
1250
  };
1251
- var Blocking = {
1251
+ var Interception = {
1252
1252
  /**
1253
1253
  * 根据配置生成需要屏蔽的扩展名列表
1254
1254
  *
1255
- * @param {Object} [config] - 屏蔽配置,缺省则使用默认配置
1256
- * @param {boolean} [config.blockArchive] - 是否屏蔽压缩包
1257
- * @param {boolean} [config.blockExecutable] - 是否屏蔽可执行文件
1258
- * @param {boolean} [config.blockDocument] - 是否屏蔽办公文档
1259
- * @param {boolean} [config.blockImage] - 是否屏蔽图片
1260
- * @param {boolean} [config.blockMedia] - 是否屏蔽音视频
1261
- * @param {boolean} [config.blockFont] - 是否屏蔽字体
1262
- * @param {boolean} [config.blockCss] - 是否屏蔽 CSS
1263
- * @param {boolean} [config.blockOther] - 是否屏蔽其他资源
1264
- * @param {string[]} [config.customExtensions] - 额外自定义扩展名
1255
+ * @param {Object} [config] - 屏蔽配置
1265
1256
  * @returns {string[]} 需要屏蔽的扩展名列表
1266
1257
  */
1267
1258
  getBlockedExtensions(config = {}) {
@@ -1280,45 +1271,6 @@ var Blocking = {
1280
1271
  }
1281
1272
  return [...new Set(extensions)];
1282
1273
  },
1283
- /**
1284
- * 设置资源屏蔽规则
1285
- * 拦截指定扩展名的请求,优化加载速度并绕过代理问题
1286
- *
1287
- * @param {import('playwright').Page} page - Playwright Page 对象
1288
- * @param {Object} [config] - 屏蔽配置
1289
- * @returns {Promise<void>}
1290
- */
1291
- async setupBlockingResources(page, config = {}) {
1292
- const mergedConfig = { ...DEFAULT_BLOCKING_CONFIG, ...config };
1293
- const blockedExtensions = this.getBlockedExtensions(mergedConfig);
1294
- const enabledCategories = [];
1295
- if (mergedConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
1296
- if (mergedConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
1297
- if (mergedConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
1298
- if (mergedConfig.blockImage) enabledCategories.push("\u56FE\u7247");
1299
- if (mergedConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
1300
- if (mergedConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
1301
- if (mergedConfig.blockCss) enabledCategories.push("CSS");
1302
- if (mergedConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
1303
- if (mergedConfig.customExtensions?.length > 0) {
1304
- enabledCategories.push(`\u81EA\u5B9A\u4E49(${mergedConfig.customExtensions.join(",")})`);
1305
- }
1306
- logger9.start("setupBlockingResources", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
1307
- await page.route("**/*", async (route) => {
1308
- const url = route.request().url();
1309
- const urlLower = url.toLowerCase();
1310
- const shouldBlock = blockedExtensions.some((ext) => {
1311
- const urlPath = urlLower.split("?")[0];
1312
- return urlPath.endsWith(ext);
1313
- });
1314
- if (shouldBlock) {
1315
- logger9.debug(`blocked: ${url.substring(0, 120)}`);
1316
- return route.abort();
1317
- }
1318
- return route.continue();
1319
- });
1320
- logger9.success("setupBlockingResources", `\u5171 ${blockedExtensions.length} \u79CD\u6269\u5C55\u540D`);
1321
- },
1322
1274
  /**
1323
1275
  * 获取所有可用的扩展名分类信息
1324
1276
  *
@@ -1337,82 +1289,92 @@ var Blocking = {
1337
1289
  };
1338
1290
  },
1339
1291
  /**
1340
- * 设置 CDN 直连规则
1341
- * 对于指定域名的请求,使用 Node.js 原生 fetch 直连获取(绕过浏览器代理)
1292
+ * 设置网络拦截规则(资源屏蔽 + CDN 直连)
1293
+ *
1294
+ * 工作流程:
1295
+ * 1. 检查请求是否在屏蔽列表中 → 如果是,直接 abort
1296
+ * 2. 检查是否匹配直连域名 → 如果是,使用 Node.js fetch 直连
1297
+ * 3. 其他请求正常走代理
1342
1298
  *
1343
1299
  * 适用场景:
1344
- * - 代理 IP 无法访问某些 CDN 域名(如 statics.moonshot.cn)
1300
+ * - 代理 IP 无法访问某些 CDN 域名
1345
1301
  * - 需要加速静态资源加载
1346
- *
1347
- * 注意事项:
1348
- * - 仅当代码运行在国内环境(本地/国内服务器)时,直连才能访问国内 CDN
1349
- * - 如果在海外服务器(如 Apify 云端)运行,直连仍使用海外 IP,可能依然无法访问
1302
+ * - 屏蔽不必要的资源请求
1350
1303
  *
1351
1304
  * @param {import('playwright').Page} page - Playwright Page 对象
1352
1305
  * @param {Object} [options] - 配置选项
1353
- * @param {string[]} [options.domains] - 需要直连的域名列表
1354
- * @param {string[]} [options.extensions] - 需要直连的扩展名列表(可选,默认 CSS/JS/字体)
1306
+ * @param {string[]} [options.directDomains] - 需要直连的域名列表
1307
+ * @param {Object} [options.blockingConfig] - 资源屏蔽配置
1355
1308
  * @param {boolean} [options.fallbackToProxy] - 直连失败时是否回退到代理(默认 true)
1356
1309
  * @returns {Promise<void>}
1357
1310
  */
1358
- async setupDirectConnect(page, options = {}) {
1311
+ async setup(page, options = {}) {
1359
1312
  const {
1360
- domains = [],
1361
- extensions = [".css", ".js", ".woff", ".woff2", ".ttf", ".otf"],
1313
+ directDomains = [],
1314
+ blockingConfig = {},
1362
1315
  fallbackToProxy = true
1363
1316
  } = options;
1364
- if (domains.length === 0) {
1365
- logger9.warn("setupDirectConnect", "\u672A\u6307\u5B9A\u57DF\u540D\u5217\u8868\uFF0C\u8DF3\u8FC7\u76F4\u8FDE\u914D\u7F6E");
1366
- return;
1367
- }
1368
- logger9.start("setupDirectConnect", `\u57DF\u540D: [${domains.join(", ")}]`);
1369
- let directCount = 0;
1370
- let fallbackCount = 0;
1317
+ const mergedBlockingConfig = { ...DEFAULT_BLOCKING_CONFIG, ...blockingConfig };
1318
+ const blockedExtensions = this.getBlockedExtensions(mergedBlockingConfig);
1319
+ const enabledCategories = [];
1320
+ if (mergedBlockingConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
1321
+ if (mergedBlockingConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
1322
+ if (mergedBlockingConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
1323
+ if (mergedBlockingConfig.blockImage) enabledCategories.push("\u56FE\u7247");
1324
+ if (mergedBlockingConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
1325
+ if (mergedBlockingConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
1326
+ if (mergedBlockingConfig.blockCss) enabledCategories.push("CSS");
1327
+ if (mergedBlockingConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
1328
+ const hasDirectDomains = directDomains.length > 0;
1329
+ logger9.start("setup", hasDirectDomains ? `\u76F4\u8FDE\u57DF\u540D: [${directDomains.join(", ")}]` : "\u4EC5\u8D44\u6E90\u5C4F\u853D\u6A21\u5F0F");
1371
1330
  await page.route("**/*", async (route) => {
1372
1331
  const request = route.request();
1373
1332
  const url = request.url();
1374
1333
  const urlLower = url.toLowerCase();
1375
1334
  const urlPath = urlLower.split("?")[0];
1376
- const matchesDomain = domains.some((domain) => url.includes(domain));
1377
- const matchesExtension = extensions.length === 0 || extensions.some((ext) => urlPath.endsWith(ext));
1378
- if (matchesDomain && matchesExtension) {
1379
- try {
1380
- const response = await fetch(url, {
1381
- method: request.method(),
1382
- headers: request.headers()
1383
- // 不传 agent 参数 = 直连(使用服务器本地网络)
1384
- });
1385
- if (!response.ok) {
1386
- throw new Error(`HTTP ${response.status}`);
1387
- }
1388
- const buffer = await response.arrayBuffer();
1389
- const body = Buffer.from(buffer);
1390
- const headers = {};
1391
- response.headers.forEach((value, key) => {
1392
- headers[key] = value;
1393
- });
1394
- directCount++;
1395
- logger9.debug(`direct: ${url.substring(0, 100)}`);
1396
- await route.fulfill({
1397
- status: response.status,
1398
- headers,
1399
- body
1400
- });
1401
- return;
1402
- } catch (e) {
1403
- if (fallbackToProxy) {
1404
- fallbackCount++;
1405
- logger9.debug(`fallback: ${url.substring(0, 80)} (${e.message})`);
1406
- return route.continue();
1407
- } else {
1408
- logger9.warn("setupDirectConnect", `\u76F4\u8FDE\u5931\u8D25\u4E14\u4E0D\u56DE\u9000: ${url.substring(0, 80)}`);
1409
- return route.abort();
1335
+ const shouldBlock = blockedExtensions.some((ext) => urlPath.endsWith(ext));
1336
+ if (shouldBlock) {
1337
+ logger9.debug(`blocked: ${url.substring(0, 100)}`);
1338
+ return route.abort();
1339
+ }
1340
+ if (hasDirectDomains) {
1341
+ const matchesDomain = directDomains.some((domain) => url.includes(domain));
1342
+ if (matchesDomain) {
1343
+ try {
1344
+ const response = await fetch(url, {
1345
+ method: request.method(),
1346
+ headers: request.headers()
1347
+ });
1348
+ if (!response.ok) {
1349
+ throw new Error(`HTTP ${response.status}`);
1350
+ }
1351
+ const buffer = await response.arrayBuffer();
1352
+ const body = Buffer.from(buffer);
1353
+ const headers = {};
1354
+ response.headers.forEach((value, key) => {
1355
+ headers[key] = value;
1356
+ });
1357
+ logger9.debug(`direct: ${url.substring(0, 100)}`);
1358
+ await route.fulfill({
1359
+ status: response.status,
1360
+ headers,
1361
+ body
1362
+ });
1363
+ return;
1364
+ } catch (e) {
1365
+ if (fallbackToProxy) {
1366
+ logger9.debug(`fallback: ${url.substring(0, 80)} (${e.message})`);
1367
+ return route.continue();
1368
+ } else {
1369
+ logger9.warn("setup", `\u76F4\u8FDE\u5931\u8D25: ${url.substring(0, 80)}`);
1370
+ return route.abort();
1371
+ }
1410
1372
  }
1411
1373
  }
1412
1374
  }
1413
1375
  return route.continue();
1414
1376
  });
1415
- logger9.success("setupDirectConnect", `\u6269\u5C55\u540D: [${extensions.join(", ")}]`);
1377
+ logger9.success("setup", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
1416
1378
  }
1417
1379
  };
1418
1380
 
@@ -1429,7 +1391,7 @@ var usePlaywrightToolKit = () => {
1429
1391
  Captcha,
1430
1392
  Sse,
1431
1393
  Errors: errors_exports,
1432
- Blocking
1394
+ Interception
1433
1395
  };
1434
1396
  };
1435
1397
  // Annotate the CommonJS export names for ESM import in node: