Go标准库net/http包的实现

 更新时间:2026年03月16日 10:08:11   作者:我叫黑大帅  
net/http是Go官方自带的 HTTP 框架,不用装任何第三方库,本文就来详细的介绍一下Go标准库net/http包的实现,感兴趣的可以了解一下

net/http 是 Go 官方自带的 HTTP 框架,不用装任何第三方库,直接就能写:

  • HTTP 服务端(写接口、网站、API)
  • HTTP 客户端(发请求、调用别人接口)

服务端

核心 API

  • http.HandleFunc(pattern, handler): 注册路由(将路径和对应的函数绑定)。
  • http.ListenAndServe(addr, handler): 启动监听并服务。「多客户端连接不阻塞」的核心!
  • http.ResponseWriter: 用于向客户端写入响应(写回数据)。
  • *http.Request: 包含客户端发来的所有信息(URL、Header、参数等)。
package main

import (
	"fmt"
	"net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
	// r.Method 可以判断是 GET 还是 POST
	fmt.Fprintf(w, "你好,你访问的路径是: %s", r.URL.Path)
}

func main() {
	// 1. 路由注册
	http.HandleFunc("/", helloHandler)

	// 2. 启动服务,监听 8080 端口
	fmt.Println("服务器启动在 http://localhost:8080")
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		panic(err)
	}
}

HandleFunc与接口函数

// `net/http` 定义了一个接口
type Handler interface {
    ServeHTTP(w http.ResponseWriter, r *http.Request)
}


func(w http.ResponseWriter, r *http.Request)
w http.ResponseWriter 给客户端返回数据(写响应)
w.Write([]byte("返回内容"))
w.WriteHeader(404) // 设置状态码
fmt.Fprintln(w, "hello") // 也可以这样写
r *http.Request 获取客户端传过来的东西
  • URL 参数
  • POST 表单 / JSON
  • 请求头
  • 请求方法(GET/POST)

常用的 5 种HandleFunc用法

处理 GET 请求(获取 URL 参数)

http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
	// 获取 ?name=xxx & age=xxx
	name := r.URL.Query().Get("name")
	age := r.URL.Query().Get("age")

	w.Write([]byte("名字:" + name + " 年龄:" + age))
})

处理 POST 表单(前端提交数据)

http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
	// 解析 POST 表单
	r.ParseForm()

	// 获取表单参数
	username := r.PostForm.Get("username")
	password := r.PostForm.Get("password")

	w.Write([]byte("用户名:" + username + " 密码:" + password))
})

返回 JSON(写 API 接口)

type User struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

http.HandleFunc("/json", func(w http.ResponseWriter, r *http.Request) {
	user := User{Name: "张三", Age: 20}

	// 设置返回格式 JSON
	w.Header().Set("Content-Type", "application/json")

	// 编码并返回
	json.NewEncoder(w).Encode(user)
})

路由分组 / 多个接口

// 首页
http.HandleFunc("/", homeHandler)

// 用户相关
http.HandleFunc("/user/list", userListHandler)
http.HandleFunc("/user/info", userInfoHandler)

// 登录
http.HandleFunc("/login", loginHandler)

访问静态文件服务

// 访问 /static/ 下的文件 
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

ServeMux 与自定义 Handler

mux := http.NewServeMux()
mux.HandleFunc("/user", userHandler)
// 将 mux 传入 ListenAndServe
http.ListenAndServe(":8080", mux)

直接使用 http.HandleFunc (默认模式)

当你直接调用 http.HandleFunc 时,Go 会在后台使用一个全局默认的实例,叫 DefaultServeMux

  • 优点:代码少,写个小脚本测试非常快。
  • 缺点:它是全局共享的。如果你引入的第三方库也偷偷在 DefaultServeMux 上注册了路由,可能会产生冲突。此外,在单元测试中,全局变量会让测试变得互相干扰。

使用 http.NewServeMux() (自定义模式)

当你创建自己的 mux 时,你是在创建一个隔离的路由表

  • 优点:更安全、更灵活。你可以创建多个 mux,分别跑在不同的端口上,或者在测试时轻松地替换它。
package main

import (
	"fmt"
	"net/http"
)

func main() {
	// --- 局部变量 1:给普通用户的路由 ---
	userMux := http.NewServeMux()
	userMux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "这是【普通用户】的个人中心")
	})

	// --- 局部变量 2:给管理员的路由 ---
	adminMux := http.NewServeMux()
	adminMux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "这是【管理员】的用户管理界面")
	})

	// 在 8080 端口启动用户服务
	go http.ListenAndServe(":8080", userMux)

	// 在 9090 端口启动管理服务
	fmt.Println("服务已启动:8080 为用户,9090 为管理")
	http.ListenAndServe(":9090", adminMux)
}

客户端

常用 API

  • http.Get(url): 发送简单的 GET 请求。
  • http.Post(url, contentType, body): 发送 POST 请求。
  • http.Client: 如果需要设置超时、Header 等高级操作,需要自定义 Client。
resp, err := http.Get("https://api.github.com")
if err != nil {
    log.Fatal(err)
}
// 记得关闭 Body,防止内存泄漏
defer resp.Body.Close()

// 读取响应内容
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))

到此这篇关于Go标准库net/http包的实现的文章就介绍到这了,更多相关Go标准库net/http包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言中双Token登录系统的思路与实现详解

    Go语言中双Token登录系统的思路与实现详解

    在现代Web应用中,身份认证是保障系统安全的重要环节,本文将介绍如何使用Go语言实现双Token登录系统,文中的示例代码讲解详细,需要的可以了解下
    2025-07-07
  • Golang极简入门教程(三):并发支持

    Golang极简入门教程(三):并发支持

    这篇文章主要介绍了Golang极简入门教程(三):并发支持,本文讲解了goroutine线程、channel 操作符等内容,需要的朋友可以参考下
    2014-10-10
  • golang 熔断器的实现过程

    golang 熔断器的实现过程

    这篇文章主要介绍了golang 熔断器的实现过程,Go 项目中使用熔断技术提高系统容错性。接下俩就来给打家介绍 go 熔断器和其使用,需要的朋友可以参考一下
    2022-01-01
  • Go标准库http与fasthttp服务端性能对比场景分析

    Go标准库http与fasthttp服务端性能对比场景分析

    这篇文章主要介绍了Go标准库http与fasthttp服务端性能比较,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Golang中的int类型和uint类型到底有多大?

    Golang中的int类型和uint类型到底有多大?

    int和uint类型在我们日常开发中经常会用到,但有个疑问就是这两个类型有多大,通过各种尝试最终得到了答案,所以下面这篇文章主要给大家介绍了关于Golang中的int类型和uint类型到底有多大的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-12-12
  • 如何使用Go操作SQLite

    如何使用Go操作SQLite

    文章介绍了如何使用Go语言操作SQLite数据库,推荐使用github.com/mattn/go-sqlite3驱动,涵盖了安装驱动、连接数据库、表的创建与删除、数据的增删改查操作,并提供了一个完整的示例代码,这为学习Go语言操作SQLite提供了一个基础案例,感兴趣的朋友一起看看吧
    2025-10-10
  • GoLang中sql.Exec()报错解决办法

    GoLang中sql.Exec()报错解决办法

    这篇文章主要给大家介绍了关于GoLang中sql.Exec()报错的解决办法,文中通过代码介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • 一文详解kubernetes 中资源分配的那些事

    一文详解kubernetes 中资源分配的那些事

    这篇文章主要为大家介绍了kubernetes 中资源分配的那些事,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • golang 如何通过反射创建新对象

    golang 如何通过反射创建新对象

    这篇文章主要介绍了golang 通过反射创建新对象的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 解决Golang小数float64在实际工程中加减乘除的精度问题

    解决Golang小数float64在实际工程中加减乘除的精度问题

    这篇文章主要介绍了解决Golang小数float64在实际工程中加减乘除的精度问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03

最新评论