电话
400 9058 355
本文介绍如何通过模拟真实浏览器请求头、启用连接复用等手段,使 go 编写的链接健康检查程序不被 f5 等 web 应用防火墙(waf)拦截或拒绝,从而稳定获取目标网页状态码。
现代 Web 应用防火墙(如 F5 ASM、Cloudflare、AWS WAF)常基于请求特征进行机器人识别——不仅检查 User-Agent,还会分析请求头完整性、顺序、HTTP/1.1 行为(如 Connection: keep-alive)、Accept 与 Accept-Language 等字段是否存在及取值合理性。Go 标准库 net/http 默认发送极简请求,缺少关键浏览器头部,极易被标记为自动化工具并拦截。
要让 Go 请求“看起来像浏览器”,需主动补全以下核心请求头(以 Chrome 最新桌面版为例):
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36") req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7") req.Header.Set("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7") req.Header.Set("Accept-Encoding", "gzip, deflate") req.Header.Set("Connection", "keep-alive") req.Header.Set("Upgrade-Insecure-Requests", "1") req.Header.Set("Sec-Fetch-Dest", "document") req.Header.Set("Sec-Fetch-Mode", "navigate") req.Header.Set("Sec-Fetch-Site", "none") req.Header.Set("Sec-Fetch-User", "?1")
✅ 重要提示:Sec-* 头部(如 Sec-Fetch-*)虽非 HTTP 标准,但已被主流浏览器广泛采用,F5 等 WAF 常将其作为关键指纹。务必添加(即使 Go 不校验其语义)。
此外,还需优化客户端配置以增强真实性:
完整改进版函数示例如下:
func fetchURL(urlStr string, timeout time.Duration) (int, error) {
client := &http.Client{
Timeout: timeout,
Transport: &http.Transport{
// 复用连接,模拟浏览器持久化连接行为
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
IdleConnTimeout: 30 * time.Second,
},
}
req, err := http.NewRequest("GET", urlStr, nil)
if err != nil {
return 0, fmt.Errorf("failed to create request: %w", err)
}
// 模拟真实浏览器头部(请根据实际测试环境微调)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8")
req.Header.Set("Accept-Language", "en-US,en;q=0.9")
req.Header.Set("Accept-Encoding", "gzip, deflate")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("Sec-Fetch-Dest", "document")
req.Header.Set("Sec-Fetch-Mode", "navigate")
req.Header.Set("Sec-Fetch-Site", "none")
req.Header.Set("Sec-Fetch-User", "?1")
resp, err := client.Do(req)
if err != nil {
return 0, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close() // 注意:defer 在函数返回前执行,确保资源释放
return resp.StatusCode, nil
}⚠️ 注意事项:
总之,“像浏览器” ≠ 仅改 UA,而是系统性地匹配 HTTP 协议层的行为指纹。从请求头完整性、连接策略到 TLS 握手特征,每一步都可能是 WAF 的判断依据。精准模拟,方能稳定通行。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...