0

0

Go 中实现选择性重定向跟随与中间 URL 捕获的完整教程

花韻仙語

花韻仙語

发布时间:2026-01-06 21:06:53

|

815人浏览过

|

来源于php中文网

原创

Go 中实现选择性重定向跟随与中间 URL 捕获的完整教程

go 的 `http.client` 支持在重定向链中主动中断并安全获取上一个有效响应,无需自定义 `roundtripper`;通过返回特定错误(如自定义 `paywalled` 错误)触发中断,同时仍可访问 `resp.request.url` 获取跳转路径中的关键中间 url。

在构建 URL 解析类工具(如 Twitter 链接展开器、短链解析服务或反爬友好型爬虫)时,常需控制 HTTP 重定向行为:既不能盲目跟随所有跳转(可能落入付费墙、登录页或广告落地页),也不能完全禁用重定向(否则无法解析 t.co、bit.ly 等短链)。Go 标准库提供了优雅的解决方案——利用 http.Client.CheckRedirect 回调函数配合错误语义,实现「选择性中断 + 中间结果捕获」。

关键原理在于:当 CheckRedirect 返回非 nil 错误时,client.Get() 不会直接 panic 或丢弃响应,而是返回最后一个成功响应(*http.Response)和该错误(包装为 *url.Error)。这意味着你可以安全地中断跳转,并立即访问 resp.Request.URL——它正是被中断前那次请求所指向的 URL(即你关心的“跳转前”地址,例如新闻源主站而非 registration.ft.com)。

以下是一个生产就绪的示例,展示如何拦截已知付费墙域名并提取有效目标 URL:

皮卡智能
皮卡智能

AI驱动高效视觉设计平台

下载
package main

import (
    "errors"
    "fmt"
    "net/http"
    "net/url"
    "strings"
)

// 自定义错误类型,用于标识“应主动终止重定向”的场景
var ErrPaywalled = errors.New("redirect would land on paywall")

// 维护需拦截的敏感主机列表(支持子域名匹配)
var blockedHosts = map[string]error{
    "registration.ft.com": ErrPaywalled,
    "login.reuters.com":   ErrPaywalled,
    "www.bloomberg.com":   ErrPaywalled, // 示例:实际中建议更精确匹配路径或使用正则
}

// 构建定制化 HTTP 客户端
var client = &http.Client{
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
        // ✅ 防止重定向环(生产环境必备)
        if len(via) >= 10 {
            return fmt.Errorf("stopped after 10 redirects")
        }

        host := req.URL.Host
        // ✅ 支持子域名匹配(如 "sub.login.reuters.com" → 匹配 "login.reuters.com")
        for pattern, err := range blockedHosts {
            if strings.HasSuffix(host, "."+pattern) || host == pattern {
                return err
            }
        }
        return nil // 允许继续重定向
    },
}

func resolveURL(input string) (*url.URL, error) {
    resp, err := client.Get(input)
    defer func() {
        if resp != nil && resp.Body != nil {
            resp.Body.Close()
        }
    }()

    // ✅ 正确解包错误:仅当 err 是 *url.Error 且其内部错误为 ErrPaywalled 时,视为“预期中断”
    if urlErr, ok := err.(*url.Error); ok {
        if urlErr.Err == ErrPaywalled {
            return resp.Request.URL, nil // ✅ 成功获取中间 URL!
        }
    }

    // 其他错误(网络失败、超时、非 paywall 类中断等)需真实报错
    if err != nil {
        return nil, err
    }

    // 无重定向或重定向完成:返回最终 URL
    return resp.Request.URL, nil
}

func main() {
    // 示例:解析金融时报短链,预期在到达 registration.ft.com 前中断
    finalURL, err := resolveURL("http://on.ft.com/14pQBYE")
    if err != nil {
        fmt.Printf("解析失败: %v\n", err)
        return
    }
    fmt.Printf("解析结果: %s\n", finalURL.String())
}

? 重要注意事项

  • 不要忽略 resp.Body.Close():即使重定向被中断,resp.Body 仍需关闭,否则会导致连接泄漏;
  • 必须检测重定向环:via 参数包含历史请求链,长度超限(如 ≥10)应主动返回错误,避免无限跳转;
  • 主机匹配建议增强:示例中使用 strings.HasSuffix 支持子域名,生产环境可结合 net.ParseIP 或正则提升精度;
  • 错误处理需区分语义:ErrPaywalled 是业务逻辑中断信号,不是异常,调用方应将其视为成功路径的一部分;
  • 超时与重试需单独配置:CheckRedirect 不影响超时,务必为 client.Timeout 或 context.WithTimeout 显式设置。

通过该模式,你既能保持标准 http.Client 的简洁性与可靠性,又能精准掌控重定向流程,在内容聚合、SEO 分析、隐私友好的链接预览等场景中实现高价值的 URL 路径洞察。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

293

2023.10.25

http500解决方法
http500解决方法

http500解决方法有检查服务器日志、检查代码错误、检查服务器配置、检查文件和目录权限、检查资源不足、更新软件版本、重启服务器或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

407

2023.11.09

http请求415错误怎么解决
http请求415错误怎么解决

解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。更多http请求415错误怎么解决的相关内容,可以阅读下面的文章。

418

2023.11.14

HTTP 503错误解决方法
HTTP 503错误解决方法

HTTP 503错误表示服务器暂时无法处理请求。想了解更多http错误代码的相关内容,可以阅读本专题下面的文章。

2196

2024.03.12

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2065

2024.08.16

seo页面描述
seo页面描述

一个好的SEO页面描述应该包含关键词、简明扼要地概括网页的主题和内容、具有吸引力、与网页内容相符,并且是独特的。它不仅可以帮助搜索引擎了解网页的内容,还可以吸引用户点击进入网页。因此,编写一个优秀的SEO页面描述对于网页的排名和点击率都非常重要。

213

2023.08.31

wordpress seo
wordpress seo

WordPress网站SEO优化方法有:1、选择一个SEO友好的主题,具有清晰的代码结构,快速的加载速度和响应式设计;2、使用SEO插件,优化你的标题标签,元描述,关键字,XML站点地图等;3、优化你的内容,内容是SEO优化的核心;4、优化你的网站速度;5、创建友好的URL;6、使用内部链接;7、优化图像;8、使用社交媒体;9、定期更新你的网站;10、监控和分析你的网站等等。

418

2023.09.18

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

2

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号