一篇文章解决go的net/http包

本文介绍了Go语言中net/http包的基础知识,包括HTTP协议概念,构建服务器、发送HTTP请求、设置请求头,以及GET和POST请求的示例。同时涵盖了net/url包的使用,如URL解析和参数传递。
摘要由CSDN通过智能技术生成

Go基础 — net/http包

知识转载于李文周博客

1. Http协议

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。

Go语言内置的 net/http包提供了HTTP客户端和服务端的实现

2. net/http net/url包常用方法

2.1 net/http

2.1.1构建服务器
  • http.HandleFunc : 用于注册HTTP请求的处理函数,接受两个参数:一个URL路径和一个处理函数(handler),当服务器收到匹配该url路径的请求时,将调用相应的处理函数来处理请求
http.HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))

http.ResponseWriter 用于写入响应数据
http.Request 表示http请求的信息

  • http.ListenandServer:用于创建一个简单的HTTP服务器,监听指定的地址和端口,并提供服务
http.ListenAndServe(addr string, handler http.Handler) error

addr:要监听的地址,格式为host:port
handler:用于处理HTTP请求的处理器

示例

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello,My net/http")
	})

	if err := http.ListenAndServe(":9090", nil); err != nil {
		panic(err)
	}
}
2.1.2 发送HTTP请求

net/http 包提供了多种方法来发送 HTTP 请求,比如 http.Get、http.Post等 详细见下文 3.基本的HTTP/HTTPS请求

2.1.3 设置请求头
  • http.NewRequest:创建自定义的http请求
http.NewRequest(method, url string, body io.Reader) (*http.Request, error)

method:请求方法,例如“GET” “POST” “PUT” 等
url:请求的目标URL
body:请求体,通常是一个实现了io.Reader接口的对象

示例

package main

import (
    "fmt"
    "net/http"
)

func main() {
    // 创建一个 GET 请求到指定 URL
    req, err := http.NewRequest("GET", "https://example.com", nil)
    if err != nil {
        panic(err)
    }

    // 发送请求并获取响应
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    // 处理响应...
}

2.2 net/url

  • url.Parse:解析URL字符串并返回url.URL结构体 其中包含URL的各个组成部分
url.Parse(rawurl string) (*url.URL, error):
parsedURL, err := url.Parse("https://example.com/path?foo=bar&baz=qux")
  • url.URL{}: 创建一个空的url.URL结构体,然后可以通过字段赋值的方式构建URL
  • u.String() string:将url.URL结构体转换为字符串形式的URL
u := url.URL{
    Scheme: "https",
    Host:   "example.com",
    Path:   "/path",
}
  • url.ParseRequestURI:用于解析请求的 URI(Uniform Resource Identifier),返回一个 url.URL 结构体。
url.ParseRequestURI(rawurl string) (*url.URL, error)
package main

import (
    "fmt"
    "net/url"
)

func main() {
    // 解析 URI
    uri := "http://example.com/path/to/resource?query=value"
    parsedURL, err := url.ParseRequestURI(uri)
    if err != nil {
        panic(err)
    }

    // 输出解析结果
    fmt.Println("Scheme:", parsedURL.Scheme)
    fmt.Println("Host:", parsedURL.Host)
    fmt.Println("Path:", parsedURL.Path)
    fmt.Println("Query:", parsedURL.RawQuery)
}


3. 基本的HTTP/HTTPS请求

  • Get、Head、Post和PostForm 发出HTTP/HTTPS请求
resp, err := http.Get("http://example.com/")

resp, err := http.Post("http://example.com/upload","image/jpeg",&buf)

resp, err := hrrp.PostForm("http://example.com/form",url.Values{"key":{"Value"},"id":{"123"}})

程序在使用完response后必须关闭回复的主体

resp , err := http.Get("http://example.com/")
if err != null{
   //handle error
}
defer resp.Body.Close()
body,err := ioutil.ReadALL(resp.Body)

4. Get请求案例

  • 使用net/http包编写一个简单的发送HTTP请求的Client端,代码如下
package main

import(
  "fmt"
  "io/ioutil"
  "net/http"
 )

func main(){
  resp, err := http.Get("https://www.example.com/")
  if err != nil {
    fmt.Printf("get failed, err:%v\n",err)
    return
   }
   defer resp.Body.Close()
   body,err := ioutil.ReadAll(resp.Body)
   if err != nil{
      fmt.Printf("read from resp.Body failed, err:%v\n",err)
      return
     }
    fmt.Print(string(body)) 

将上面的代码保存之后编译成可执行文件,执行之后就能在终端打印example.com网站首页的内容了,我们的浏览器其实就是一个发送和接收HTTP协议数据的客户端,我们平时通过浏览器访问网页其实就是从网站的服务器接收HTTP数据,然后浏览器会按照HTML、CSS等规则将网页渲染展示出来。

5.带参数的GET请求案例

关于GET请求的参数需要使用Go语言内置的net/url这个标准库来处理。

func main(){
  apiUrl := "http://127.0.0.1:9090/get"
  data := url.Values{}
  data.Set("name","小王子")
  data.Set("age","18")
  u,err := url.ParseRequestURI(apiUrl)
  if err != nil {
    fmt.Printf("post failed, err:%v\n",err)
    return
}
defer resp.Body.Close()
b,err := ioutil.ReadAll(resp.Body)
if err != nil {
   fmt.Printf("get resp failed, err:%v\n",err)
   return
   }
fmt.Println(string(b))
}  

对应的Server端HandlerFunc如下:

func getHandler(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	data := r.URL.Query()
	fmt.Println(data.Get("name"))
	fmt.Println(data.Get("age"))
	answer := `{"status": "ok"}`
	w.Write([]byte(answer))
}

6.Post请求

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

// net/http post demo

func main() {
	url := "http://127.0.0.1:9090/post"
	// 表单数据
	//contentType := "application/x-www-form-urlencoded"
	//data := "name=小王子&age=18"
	// json
	contentType := "application/json"
	data := `{"name":"小王子","age":18}`
	resp, err := http.Post(url, contentType, strings.NewReader(data))
	if err != nil {
		fmt.Printf("post failed, err:%v\n", err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("get resp failed, err:%v\n", err)
		return
	}
	fmt.Println(string(b))
}

对应的Server端 HandlerFunc 如下

func postHandler(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	// 1. 请求类型是application/x-www-form-urlencoded时解析form数据
	r.ParseForm()
	fmt.Println(r.PostForm) // 打印form数据
	fmt.Println(r.PostForm.Get("name"), r.PostForm.Get("age"))
	// 2. 请求类型是application/json时从r.Body读取数据
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Printf("read request.Body failed, err:%v\n", err)
		return
	}
	fmt.Println(string(b))
	answer := `{"status": "ok"}`
	w.Write([]byte(answer))
}

  • 27
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值