[Go关于网络请求] net/http库

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Go关于网络请求] net/http库相关的知识,希望对你有一定的参考价值。

文章目录

带参数的GET请求

client

package main

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

func main() 
	apiUrl := "http://127.0.0.1:8081/json"
	// data用于构建url的参数,url.Values底层是一个map
	data := url.Values  
	//data.Set("name", "小王子")
	data.Set("age", "18")
	u, err := url.ParseRequestURI(apiUrl)  //把字符串转化为url对象
	if err != nil 
		fmt.Printf("parse url requestUrl failed, err:%v\\n", err)
	
	u.RawQuery = data.Encode() // 把所有参数用&连起来,并解析掉特殊符号(中文等)

	resp, err := http.Get(u.String())
	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

package main

import (
	"github.com/gin-gonic/gin"
)

func main() 
	r := gin.Default()
	r.GET("/json",func(c *gin.Context)
		name := c.Query("name")
		age := c.Query("age")
		if name==""
			name = "参数内没有name"
		
		if age==""
			age = "参数内没有age"
		
		c.JSON(200,gin.H
			"name":name,
			"age":age,
		)
	)
	r.Run(":8081")

带参数的POST请求

client

package main

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

func main() 
	URL := "http://127.0.0.1:8081/json"

	contentType := "application/x-www-form-urlencoded"
	data := url.Values
	data.Set( "name","cl" )
	data.Add( "age","18" )
	resp, err := http.Post(URL, contentType, strings.NewReader(data.Encode()))
	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

package main

import (
	"github.com/gin-gonic/gin"
)

func main() 
	r := gin.Default()
	r.POST("/json",func(c *gin.Context)

		name := c.PostForm("name")
		age := c.PostForm("age")
		if name==""
			name = "参数内没有name"
		
		if age==""
			age = "参数内没有age"
		
		c.JSON(200,gin.H
			"name":name,
			"age":age,
		)
	)
	r.Run(":8081")

http.client的使用

如果牵涉到设置请求头信息,处理跨域之类的配置,就需要使用到http.client

设置请求头字段

下面是一个请求百度的例子

package main

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

func main() 
	req, err := http.NewRequest("GET", "http://www.baidu.com/", nil)
	if err != nil 
		log.Fatal(err)
	

	req.Header.Add("User-Agent", "gwy test user agent")

	//2.client
	client := &http.Client
	resp, err := client.Do(req)
	if err != nil 
		log.Fatal(err)
	

	//3.body
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil 
		log.Fatal(err)
	

	fmt.Println("body:%v", string(body))

设置重定向策略

通过设置client对象的CheckRedirect,可以在重定向之前先做一些其他的操作

server

package main

import (
	"log"
	"net/http"
)

func main() 
	helloHandler := func(w http.ResponseWriter, req *http.Request) 
		w.Header().Set("Location", "http://127.0.0.1:8088/hello")
		w.WriteHeader(302)
	
	http.HandleFunc("/test", helloHandler)
	log.Fatal(http.ListenAndServe(":8087", nil))

client端口

package main

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

func Redirect302(req *http.Request, via []*http.Request) error 
	fmt.Println("---------url:", req.URL.Host)
	fmt.Println("---------url:", req.URL.Path)
	fmt.Println("---------url:", req.URL.Opaque)

	//req.URL.Host = "www.baidu.com"
	//req.URL.Path = "/"

	return nil


func main() 
	//1.request
	req, err := http.NewRequest("GET", "http://127.0.0.1:8087/test", nil)
	if err != nil 
		log.Fatal(err)
	

	req.Header.Add("User-Agent", "gwy test user agent")

	//2.client
	client := &http.Client
		CheckRedirect: Redirect302,
	
	resp, err := client.Do(req)
	if err != nil 
		log.Fatal(err)
	

	fmt.Println("status_code:", resp.StatusCode)

	//3.body
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil 
		log.Fatal(err)
	

	fmt.Println("body:", string(body))

使用http.client, POST携带JSON数据&接收

client

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

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


func main() 
	client := &http.Client
	user := User "cl",20 
	mm,_ := json.Marshal(user)

	req,_ := http.NewRequest("POST","http://127.0.0.1:8088/json",bytes.NewReader(mm) )

	req.Header.Set("Content-Type", "application/json")
	//req.Header.Set("Content-Type","application/x-www-form-urlencoded")
	resp,err := client.Do( req )
	if err != nil
		fmt.Println( err.Error() )
		return
	
	msg,_ := ioutil.ReadAll(resp.Body)
	fmt.Println( string(msg) )

server

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)
type User struct
	Name string `json:"name"`
	Age int `json:"age"`


func main() 
	r := gin.Default()
	r.POST("/json",func(c *gin.Context)
		var user User
		c.ShouldBindJSON( &user )
		name := c.Query("name")
		age := c.Query("age")
		fmt.Printf("%+v\\n",user )
		fmt.Printf( "name = %v, age = %v\\n", name, age )
		if name==""
			name = "参数内没有name"
		
		if age==""
			age = "参数内没有age"
		
		c.JSON(200,gin.H
			"name":name,
			"age":age,
		)
	)
	r.Run(":8088")


跳过证书检测&使用http2.0协议

通过设置Transport来设置,本次请求不校验服务端的证书

	httpCli = &http.Client
		Transport: &http.Transport
			ForceAttemptHTTP2: true,  //使用http2.0
			TLSClientConfig: &tls.Config
				InsecureSkipVerify: true,  //接收任何证书
			,
		,
	

以上是关于[Go关于网络请求] net/http库的主要内容,如果未能解决你的问题,请参考以下文章

[Go关于网络请求] net/http库

基于标准库 net/http 如何记录 HTTP 请求?

Go基础库之net/http

关于Go net/http 超时完全指南

go 网络请求篇二

Go——标准库使用代理