You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js与浏览器HTTP请求差异:API反爬检测问题排查

问题分析与解决办法

问题概述

用Node.js代码调用目标API时,触发「API异常使用检测」,被判定为「VPN/Proxy检测」并返回403 Forbidden状态码。但VS Code的Thunder Client插件、Firefox浏览器直接请求该API完全正常,仅自研代码或Burp Suite这类中间件请求会被拦截。

已验证的测试细节

  • 核对过请求头完全一致,但Thunder Client将协议从HTTP/1.1切换为HTTP/2后,请求会被检测拦截;
  • Thunder Client疑似使用SOCKS代理,启用Requestly.io代理后,Thunder Client和Firefox的请求均被判定为UNAUTHORIZED_PROXY;
  • 尝试过axios、原生fetch、node-fetch、request等Node.js HTTP库,切换HTTP协议版本后问题仍存在。

示例代码

const req = await fetch("https://mywebsite.com/", {
    headers: {
        "Connection": "close", // 也试过keep-alive
        "Accept-encoding": "gzip",
        "Accept": "*/*",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0",
        "Content-Type": "application/json",
        "Authorization": "Bearer MyToken"
    }
})
const response = await req.json()
console.log(response) // 返回403 Forbidden

可能的原因

  1. HTTP/2协议实现差异:浏览器与Node.js的HTTP/2底层实现细节不同,比如帧优先级、SETTINGS参数等,服务器可通过这些特征识别非浏览器请求;
  2. TCP/TLS指纹不一致:Node.js的网络栈与浏览器存在差异,比如TCP握手初始窗口大小、TLS握手的加密套件顺序、TLS扩展字段等,这些指纹会被服务器的反爬系统捕捉;
  3. 请求行为模式差异:浏览器发起请求的时序、连接复用逻辑与Node.js脚本不同,服务器可能通过行为模型判断请求是否来自自动化工具;
  4. 中间件隐性标记:Burp Suite等代理工具会在请求中留下隐性特征(如TLS会话的特殊扩展),导致被检测识别。

解决办法

1. 使用更贴近浏览器的HTTP库

推荐使用undici,它的HTTP/2实现更接近Chrome/Firefox的行为,能减少协议层面的指纹差异:

import { fetch, Agent } from 'undici';

const agent = new Agent({
    connect: {
        // 匹配Firefox 125的TLS加密套件顺序
        ciphers: 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384',
        // 启用ALPN,匹配浏览器的协议协商顺序
        ALPNProtocols: ['h2', 'http/1.1']
    }
});

const req = await fetch("https://mywebsite.com/", {
    headers: {
        "Accept-encoding": "gzip",
        "Accept": "*/*",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0",
        "Content-Type": "application/json",
        "Authorization": "Bearer MyToken"
    },
    dispatcher: agent
});
const response = await req.json();
console.log(response);

2. 强制使用HTTP/1.1

部分服务器对HTTP/1.1的指纹检测更宽松,可强制Node.js使用HTTP/1.1协议:

const https = require('https');
const { fetch } = require('node-fetch');

const agent = new https.Agent({
    // 禁用HTTP/2,强制使用HTTP/1.1
    ALPNProtocols: ['http/1.1'],
    // 匹配浏览器的TLS加密套件
    ciphers: 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'
});

const req = await fetch("https://mywebsite.com/", {
    headers: { /* 保持原请求头 */ },
    agent: agent
});

3. 消除TCP/TLS指纹差异

手动配置Node.js的TLS参数,完全匹配目标浏览器的配置:

  • 查找目标浏览器(如Firefox 125)的TLS加密套件顺序、ALPN协议列表;
  • 使用Node.js的tls模块自定义Agent的这些参数。

4. 模拟浏览器请求时序

在发起API请求前,添加随机延迟(模拟用户操作时间),或先请求一个静态资源(如网站的favicon.ico),再发起目标API请求,模仿浏览器的行为流程。

5. 禁用系统代理

Node.js可能默认使用系统代理,导致与浏览器的代理环境不一致,可在代码中明确禁用代理:

const agent = new https.Agent({ proxy: false });
// 在fetch/axios中使用该agent

内容的提问来源于stack exchange,提问作者antgol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:30:58