← [ BACK_TO_NOTES ]

Learn HTTP Clients in Go(Boot.dev)

Boot.dev HTTP 客户端课程的个人学习记录:JSON、URL、请求头、方法以及传输错误与 HTTP 状态的区别。

#resource #growing #education #boot-dev #go #course

Learn HTTP Clients in Go(Boot.dev)

[!info] related notes

概览

boot.dev 上的 learn http clients in go 课程 主要记录 Go 作为客户端时需要掌握的知识;不是课程完整大纲或完成证明。

why http

这一章节讲了大致下面内容:

  1. 本课场景通过 HTTP 获取数据;net/http 的响应体是 io.ReadCloser 字节流,读取后可得到 []byte,也可直接解码。
  2. 基础的 front-end、back-end、client、server、URL、http等的概念
  3. go 一般使用自带的 net/http 标准库来进行请求

JSON

  1. 讲了 JSON定义
  2. encoding/json 可对字节切片进行 Marshal/Unmarshal,也可用 Decoder/Encoder 处理 Reader/Writer。下面是处理响应的函数内片段,假定已定义 Issue、检查请求错误与状态码,并安排响应体关闭。
var issues []Issue // 定义一个 issues
decoder := json.NewDecoder(res.Body) // 创建解码器
if err := decoder.Decode(&issues); err != nil {  // 解码器填充 issues
	fmt.Println("error decoding response body")
	return nil, fmt.Errorf("decode response body: %w", err)
}

json.Unmarshal 处理完整的 JSON 字节切片。以下对比片段只适用于响应大小已有可信上界的场景;对任意远端响应直接 io.ReadAll 会无界占用内存。

// res is an http.Response
defer res.Body.Close()

data, err := io.ReadAll(res.Body)
if err != nil {
	return nil, err
}

var issues []Issue
if err := json.Unmarshal(data, &issues); err != nil {
    return nil, err
}
  1. json.Marshal go struct 转为 JSON 数据
  2. map[string]any 可表示动态 JSON 对象;默认解码到接口时数字成为 float64。稳定结构优先用类型明确的 struct,需要保留数字文本时考虑 Decoder.UseNumber()。

单次 Decode 只消费一个 JSON 值,不证明后面没有其他数据。接口要求整个响应只能有一个值时,还需确认后续为 EOF,见 JSON 与序列化。

URL 解析与 DNS 的区别

net/url 解析 URL 的组成部分,不进行 DNS 查询。Hostname() 只是取出主机名;DNS 地址解析是另一项工作,见 URL 和 DNS。

parsedURL, err := url.Parse("https://homestarrunner.com/toons") 
if err != nil {
	fmt.Println("error parsing url:", err)
	return
}


parsedURL.Hostname()
// homestarrunner.com

URIs

URI 是统一资源标识符(Uniform Resource Identifier);URL 是统一资源定位符(Uniform Resource Locator)。URI 可以具有定位、命名或两者兼有的作用,不能把 URL 和 URN 简化为互斥且穷尽的两类。

URL struct

http://testuser:testpass@testdomain.com:8080/testpath?testsearch=testvalue#testhash 以下 ParsedURL 是课程练习自定义结构,不是标准库 url.URL 的字段定义;示例用户名和密码仅用于拆解格式:

return ParsedURL{
	protocol: "http",
	username: "testuser",
	password: "testpass",
	hostname: "testdomain.com",
	port:     "8080",
	pathname: "/testpath",
	search:   "testsearch=testvalue",
	hash:     "testhash",
}

Use these fields and methods of the URL struct:

  • Scheme
  • User.Username()
  • User.Password() - this method returns two values: the password if set and whether it was set
  • Hostname()
  • Port()
  • Path
  • RawQuery
  • Fragment

Scheme 如 http、https、ftp、mailto;并非每种 scheme 都对应网络协议,也并非都需要 //,例如 mailto:noreply@jello.app。URL fragment 通常不随 HTTP 请求发送给服务器。

headers

请求头

主要记录创建请求、设置请求头和读取响应头。下面是函数内片段,需导入 fmt、net/http、time;实际应用可复用带超时的 Client。

// creating a new request
req, err := http.NewRequest("GET", "https://api.example.com/users", nil)
if err != nil {
	fmt.Println("error creating request: ", err)
	return
}

// setting a header on the new request
req.Header.Set("Accept", "application/json")

// making the request
client := http.Client{Timeout: 10 * time.Second}
res, err := client.Do(req)
if err != nil {
	fmt.Println("error making request: ", err)
	return
}
defer res.Body.Close()

// reading a header from the response
header := res.Header.Get("last-modified")
fmt.Println("last modified: ", header)

// 只修改本地响应对象中的 Header,不影响服务器或已完成的网络传输
res.Header.Del("last-modified")

请求头可携带认证信息,也用于内容协商、缓存条件等;收到响应后应检查 res.StatusCode,不能只检查 err。

Method

put,post,delete,patch,get 等语义方法

error

在实际的网络开发中,发起请求并不总是顺畅无阻的。背后的核心知识点可以分为以下两大部分:

1. 请求执行错误

这类错误表示客户端没有完成预期的请求流程,可能发生在发送前,也可能发生在服务端已经执行操作之后。超时不能证明请求未到达,重试写操作需考虑幂等性。

  • 原因:URL 无效、DNS 失败、连接或读取超时、TLS/协议问题,也可能是客户端重定向策略拒绝。
  • Go 中的表现:调用 http.Get(url) 会直接返回一个非空的 err。
  • 处理逻辑:先处理 err,不要假设 res 非空。标准 Client 因 CheckRedirect 失败可能同时返回 response 和 error,但该响应体已关闭;不要把“HTTP 状态码 0”当作服务器返回值。

2. HTTP 非成功状态

这类错误发生在网络连接正常建立,并且服务器也成功返回了 HTTP 响应,但返回的状态码指示请求出了问题。

  • 原因:例如请求的资源不存在(404 Not Found)、未授权访问(401 Unauthorized)、服务器内部报错(500 Internal Server Error)等。
  • Go 中的表现:http.Get(url) 返回的 err 为 nil,因为从网络协议角度来看通信是成功的。但是响应对象 res 中的 StatusCode 字段会反应具体的状态(如 404、500 等)。
  • 处理逻辑:我们需要手动检查状态码。一般情况下,只有 200 到 299 范围内的状态码(如 http.StatusOK 即 200)表示 HTTP 层成功;业务结果仍需按接口契约校验,204 也不应强行解码 JSON。如果不是 200 系列,我们需要根据 res.StatusCode 或 res.Status(状态文本)单独进行错误处理,并记得关闭响应体 defer res.Body.Close()。

待继续学习

  • Path 与 HTTPS:原记录尚未展开。
  • curl 用于发起请求与检查响应,jq 用于处理 JSON。

核对依据

2026-10-06 按标准库核对技术内容;课程站访问返回 403,未据此推断课程下架或变更个人学习状态。

创建于 2026/8/1 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本