当前位置: 首页 > news >正文

Go 与 Gin 搭建简易 Postman:实现基础 HTTP 拨测的详细指南

Go 与 Gin 搭建简易 Postman:实现基础 HTTP 拨测的详细指南

文章目录

  • Go 与 Gin 搭建简易 Postman:实现基础 HTTP 拨测的详细指南
    • 项目简介
    • 代码结构
      • 各部分代码功能说明:
    • 代码实现:
      • main.go
        • 代码解释
      • handlers/probe.go
        • 代码解释
      • probe/types.go
        • 代码解释
      • probe/http.go
        • 代码解释:
      • index.html
        • 代码解释
      • style.css
        • 代码解释
    • 代码构建
      • 访问测试
    • 总结

项目简介

在日常的开发和测试工作中,我们经常需要对各种网络接口进行测试,以确保它们能够正常工作。Postman 是一款非常流行的工具,它可以帮助我们方便地发送 HTTP 请求并查看响应结果。本项目旨在实现一个简易的 Postman 工具,支持基本的 HTTP 拨测功能,用户可以通过该工具输入 URL 和请求方法,发送请求并查看响应的状态码和延迟时间。
在这里插入图片描述

代码结构

├── main.go          # 主程序入口
├── handlers         # HTTP处理器
│   └── probe.go
├── probe            # 拨测核心逻辑
│   ├── http.go
│   ├── types.go
├── static           # 前端静态文件
│   ├── index.html
│   └── style.css
└── go.mod

各部分代码功能说明:

  • main.go:作为主程序入口,负责初始化 Gin 框架,设置静态文件路由和 API 路由,并启动 HTTP 服务器。
  • handlers/probe.go:处理拨测请求,解析客户端发送的请求参数,根据协议类型调用相应的拨测函数,并返回拨测结果。
  • probe 目录:包含拨测的核心逻辑,其中 http.go 实现了 HTTP 协议的拨测功能,types.go 定义了统一的响应结构体和创建错误结果的工具函数。
  • static 目录:存放前端静态文件,index.html 是前端页面的主体,style.css 用于设置页面的样式。
  • go.mod:Go 模块文件,管理项目的依赖。

代码实现:

main.go

package mainimport ("github.com/gin-gonic/gin""time"
)type ProbeResult struct {Endpoint   string `json:"endpoint"`StatusCode int    `json:"status_code"`Duration   int64  `json:"duration"`
}func main() {r := gin.Default()// 静态文件路由r.Static("/static", "./static")r.GET("/", func(c *gin.Context) {c.File("./static/index.html")})// API路由r.POST("/api/probe", func(c *gin.Context) {// 模拟132ms延迟time.Sleep(132 * time.Microsecond)c.JSON(200, ProbeResult{Endpoint:   "http://192168.100.10:8080",StatusCode: 200,Duration:   132,})})r.Run(":8080")
}
代码解释
  • 导入 github.com/gin-gonic/gin 包用于构建 HTTP 服务器,time 包用于模拟延迟。
  • 定义 ProbeResult 结构体,用于存储拨测结果,包含端点、状态码和延迟时间。
  • main 函数中,初始化 Gin 引擎 r
  • 设置静态文件路由,将 /static 路径映射到 ./static 目录,以便前端页面可以访问静态资源。
  • 定义根路径 / 的处理函数,返回 ./static/index.html 文件。
  • 定义 /api/probe 的 POST 请求处理函数,模拟 132ms 的延迟,并返回一个示例拨测结果。
  • 最后启动服务器,监听 :8080 端口。

handlers/probe.go

package handlersimport ("net/http""strings""time""http/probe""github.com/gin-gonic/gin"
)type ProbeRequest struct {Protocol string `json:"protocol"`Method   string `json:"method"`URL      string `json:"url"`Timeout  int    `json:"timeout"`
}func ProbeHandler(c *gin.Context) {var req ProbeRequestif err := c.ShouldBindJSON(&req); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}// 自动补全协议头if !strings.Contains(req.URL, "://") {req.URL = "http://" + req.URL}start := time.Now()var result probe.ProbeResultswitch req.Protocol {case "HTTP":result = probe.HTTPProbe(req.Method, req.URL, req.Timeout)//case "TCP"://	result = probe.TCPProbe(req.URL, req.Timeout)//case "ICMP"://	result = probe.ICMPProbe(strings.Split(req.URL, "://")[1], 4)//case "SSL"://	result = probe.SSLProbe(req.URL, req.Timeout)default:c.JSON(http.StatusBadRequest, gin.H{"error": "不支持的协议类型"})return}result.Duration = time.Since(start).Milliseconds()c.JSON(http.StatusOK, result)
}
代码解释
  • 定义 ProbeRequest 结构体,用于接收客户端发送的拨测请求参数,包括协议类型、请求方法、URL 和超时时间。
  • ProbeHandler 函数是 /api/probe 接口的处理函数,首先尝试将客户端发送的 JSON 数据绑定到 ProbeRequest 结构体上,如果绑定失败则返回 400 错误。
  • 自动补全 URL 的协议头,如果 URL 中不包含 ://,则默认添加 http://
  • 记录开始时间,根据协议类型调用相应的拨测函数,目前只实现了 HTTP 协议的拨测。
  • 计算拨测的延迟时间,并将其赋值给 result.Duration
  • 最后返回拨测结果给客户端。

probe/types.go

package probe// 统一响应结构体(必须大写开头才能被外部访问)
type ProbeResult struct {Endpoint   string `json:"endpoint"`        // 探测地址StatusCode int    `json:"status_code"`     // HTTP状态码/探测状态Duration   int64  `json:"duration"`        // 延迟毫秒数Protocol   string `json:"protocol"`        // 协议类型Error      string `json:"error,omitempty"` // 错误信息
}// 创建错误结果的工具函数
func NewErrorResult(endpoint string, err error) ProbeResult {return ProbeResult{Endpoint:   endpoint,Error:      err.Error(),Protocol:   "Unknown",StatusCode: 500,}
}
代码解释
  • 定义 ProbeResult 结构体,作为统一的拨测响应结构体,包含探测地址、状态码、延迟时间、协议类型和错误信息。
  • NewErrorResult 函数是一个工具函数,用于创建一个包含错误信息的拨测结果。

probe/http.go

package probeimport ("net/http""strings""time"
)func HTTPProbe(target string) ProbeResult {start := time.Now()// 自动补全协议头if !strings.HasPrefix(target, "http") {target = "http://" + target}// 真实网络请求client := &http.Client{Timeout: 10 * time.Second}resp, err := client.Get(target)duration := time.Since(start).Milliseconds()result := ProbeResult{Endpoint: target,Duration: duration,}if err != nil {result.Error = err.Error()return result}defer resp.Body.Close()result.StatusCode = resp.StatusCodereturn result
}
代码解释:
  • HTTPProbe 函数实现了 HTTP 协议的拨测功能。
  • 记录开始时间,自动补全 URL 的协议头。
  • 创建一个 http.Client 对象,设置超时时间为 10 秒,然后发送 GET 请求。
  • 计算请求的延迟时间,并将其赋值给 result.Duration
  • 如果请求过程中出现错误,将错误信息赋值给 result.Error 并返回结果。
  • 如果请求成功,获取响应的状态码并赋值给 result.StatusCode,最后返回结果。

index.html

<!DOCTYPE html>
<html>
<head><title>是垚不是土的网络拨测工具</title><style>/* 精确还原图片样式 */body {background: #f0f2f5;font-family: Arial;margin: 0;padding: 20px;}.container {background: white;border-radius: 8px;padding: 20px;max-width: 800px;margin: 0 auto;box-shadow: 0 1px 3px rgba(0,0,0,0.12); /* 添加阴影效果 */}.tabs button {padding: 10px 24px; /* 精确匹配按钮尺寸 */border: none;background: none;cursor: pointer;border-bottom: 2px solid transparent;font-size: 14px;color: #666;}.tabs button.active {border-color: #1890ff;color: #1890ff;font-weight: bold;}.input-group {display: flex;gap: 10px;margin: 24px 0; /* 调整间距 */align-items: center;}#method {width: 100px;padding: 8px 12px;border: 1px solid #d9d9d9;border-radius: 4px;font-size: 14px;}#url {flex: 1;padding: 8px 12px;border: 1px solid #d9d9d9;border-radius: 4px;font-family: monospace; /* 代码字体 */}#probe-btn {background: #1890ff;color: white;border: none;padding: 8px 24px;border-radius: 4px;cursor: pointer;transition: opacity 0.2s;}#probe-btn:hover {opacity: 0.9;}table {width: 100%;border-collapse: collapse;margin-top: 24px;}th, td {padding: 14px 16px; /* 调整单元格间距 */border: 1px solid #e8e8e8;text-align: left;font-size: 14px;}th {background: #fafafa;font-weight: 500;}.status-code {font-family: monospace;}.status-ok {color: #52c41a; /* 精确匹配绿色 */font-weight: 500;}.status-error {color: #ff4d4f; /* 新增错误颜色 */font-weight: 500;}</style>
</head>
<body>
<div class="container"><div class="tabs"><button class="active">HTTP</button><button>ICMP</button><button>TCP</button><button>SSL</button></div><div class="input-group"><select id="method"><option>GET</option><option>POST</option></select><input type="text" id="url" placeholder="http://192.168.100.10:8080"><button id="probe-btn">拨测一下</button></div><div class="advanced">> 高级选项</div><table><thead><tr><th>端点</th><th>状态码</th><th>响应延迟</th></tr></thead><tbody id="results"><!-- 初始示例数据 --><tr><td>http://192.168.100.10:8080</td><td class="status-ok">200</td><td>132ms</td></tr><tr><td>http://192.168.100.10:80</td><td class="status-error">404</td><td>0ms</td></tr></tbody></table>
</div><script>document.getElementById('probe-btn').addEventListener('click', async () => {const url = document.getElementById('url').value;// 输入验证if (!url) {alert('请输入要拨测的URL地址');return;}try {// 发送拨测请求const response = await fetch('/api/probe', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({protocol: 'HTTP',method: document.getElementById('method').value,url: url})});if (!response.ok) throw new Error('网络请求失败');const data = await response.json();// 创建新结果行const newRow = document.createElement('tr');newRow.innerHTML = `<td>${data.endpoint}</td><td class="${data.status_code === 200 ? 'status-ok' : 'status-error'}">${data.status_code}</td><td>${data.duration}ms</td>`;// 插入到表格顶部const tbody = document.getElementById('results');tbody.insertBefore(newRow, tbody.firstChild);} catch (error) {// 错误处理const errorRow = document.createElement('tr');errorRow.innerHTML = `<td>${url}</td><td class="status-error">ERROR</td><td>0ms</td>`;document.getElementById('results').prepend(errorRow);}});
</script>
</body>
</html>
代码解释
  • 前端页面使用 HTML、CSS 和 JavaScript 实现。
  • CSS 部分设置了页面的样式,包括背景颜色、字体、按钮样式、表格样式等。
  • HTML 部分构建了页面的结构,包括选项卡、输入框、拨测按钮和结果表格。
  • JavaScript 部分实现了拨测按钮的点击事件处理逻辑:
    • 首先进行输入验证,如果用户没有输入 URL,则弹出提示框。
    • 使用 fetch API 发送 POST 请求到 /api/probe 接口,携带协议类型、请求方法和 URL 信息。
    • 如果请求成功,将响应数据解析为 JSON 格式,并创建一个新的表格行,将拨测结果显示在表格顶部。
    • 如果请求失败,创建一个包含错误信息的表格行,并显示在表格顶部。

style.css

body {font-family: Arial, sans-serif;margin: 20px;background: #f0f2f5;
}.container {background: white;border-radius: 8px;padding: 20px;max-width: 800px;margin: 0 auto;
}.tabs button {padding: 10px 20px;border: none;background: none;border-bottom: 2px solid transparent;cursor: pointer;
}.tabs button.active {border-color: #1890ff;color: #1890ff;font-weight: bold;
}.input-group {display: flex;gap: 10px;margin: 20px 0;align-items: center;
}#url {flex: 1;padding: 8px 12px;border: 1px solid #d9d9d9;border-radius: 4px;
}button {background: #1890ff;color: white;border: none;padding: 8px 20px;border-radius: 4px;cursor: pointer;
}table {width: 100%;border-collapse: collapse;margin-top: 20px;
}th, td {padding: 12px;border: 1px solid #e8e8e8;text-align: left;
}.status-200 {color: #52c41a;font-weight: 500;
}.status-error {color: #ff4d4f;font-weight: 500;
}
代码解释
  • style.css 文件用于设置页面的全局样式,包括背景颜色、字体、按钮样式、表格样式等。

代码构建

go.mod

module httpgo 1.23.0toolchain go1.23.8require (github.com/gin-gonic/gin v1.10.0github.com/go-ping/ping v1.2.0golang.org/x/net v0.40.0
)require (github.com/bytedance/sonic v1.13.2 // indirectgithub.com/bytedance/sonic/loader v0.2.4 // indirectgithub.com/cloudwego/base64x v0.1.5 // indirectgithub.com/cloudwego/iasm v0.2.0 // indirectgithub.com/gabriel-vasile/mimetype v1.4.9 // indirectgithub.com/gin-contrib/sse v1.1.0 // indirectgithub.com/go-playground/locales v0.14.1 // indirectgithub.com/go-playground/universal-translator v0.18.1 // indirectgithub.com/go-playground/validator/v10 v10.26.0 // indirectgithub.com/goccy/go-json v0.10.5 // indirectgithub.com/google/uuid v1.6.0 // indirectgithub.com/json-iterator/go v1.1.12 // indirectgithub.com/klauspost/cpuid/v2 v2.2.10 // indirectgithub.com/leodido/go-urn v1.4.0 // indirectgithub.com/mattn/go-isatty v0.0.20 // indirectgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirectgithub.com/modern-go/reflect2 v1.0.2 // indirectgithub.com/pelletier/go-toml/v2 v2.2.4 // indirectgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirectgithub.com/ugorji/go/codec v1.2.12 // indirectgolang.org/x/arch v0.17.0 // indirectgolang.org/x/crypto v0.38.0 // indirectgolang.org/x/sync v0.14.0 // indirectgolang.org/x/sys v0.33.0 // indirectgolang.org/x/text v0.25.0 // indirectgoogle.golang.org/protobuf v1.36.6 // indirectgopkg.in/yaml.v3 v3.0.1 // indirect
)

安装依赖

go mod tidy

go mod tidy 命令会自动下载项目所需的依赖包,并更新 go.modgo.sum 文件。

运行程序:

go run main.go

访问测试

http://localhost:8080

在这里插入图片描述

打开浏览器,访问 http://localhost:8080,即可看到简易 Postman 工具的界面。在输入框中输入要拨测的 URL 和请求方法,点击 “拨测一下” 按钮,即可发送请求并查看响应的状态码和延迟时间。

总结

通过本项目,我们实现了一个简易的 Postman 工具,支持基本的 HTTP 拨测功能。项目采用了前后端分离的架构,前端使用 HTML、CSS 和 JavaScript 实现用户界面,后端使用 Go 语言和 Gin 框架实现 HTTP 服务器和拨测逻辑。在实际开发中,我们可以进一步扩展该工具,支持更多的协议类型(如 TCP、ICMP、SSL 等),添加更多的请求参数(如请求头、请求体等),以及优化用户界面和错误处理逻辑。

相关文章:

  • window自带截图快捷键
  • Flutter与Kotlin Multiplatform(KMP)深度对比及鸿蒙生态适配解析
  • ubuntu防火墙命令和放行ssh端口
  • VueUse/Core:提升Vue开发效率的实用工具库
  • Popeye
  • muduo库TcpServer模块详解
  • 深入理解TCP与UDP:协议对比、头部结构与连接管理
  • WebSocket解决方案的一些细节阐述
  • WebSocket实时双向通信:从基础到实战
  • LlamaIndex中应用自定义提示词提升回答质量
  • 【25软考网工】第六章(7)网络安全防护系统
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序源码的去中心化商业扩散研究
  • 【C++】map和set的使用
  • @JsonProperty和@JSONField 使用
  • 5.18 打卡
  • Android日活(DAU)检测的四大实现方案详解
  • Android 性能优化入门(三)—— 启动速度优化
  • weibo_comment_pc_tool | 我于2025.5月用python开发的评论采集软件,根据帖子链接爬取评论的界面工具
  • 牛客网NC276110题解:小红的数组重排
  • 低延迟与高性能的技术优势解析:SmartPlayer VS VLC Media Player
  • 东航C919航线上新!正式投入上海虹桥—深圳航线运营
  • 国际博物馆日|航海博物馆:穿梭于海洋神话与造船工艺间
  • 从良渚到三星堆:一江水串起了5000年的文明对话
  • 菲律宾选举委员会公布中期选举结果,马科斯阵营选情未达预期
  • 上百家单位展示AI+教育的实践与成果,上海教育博览会开幕
  • 广西壮族自治区政府主席蓝天立任上被查