当前位置: 首页 > 工具软件 > gohttp > 使用案例 >

go的http包客户端的使用

唐繁
2023-12-01

一、基本介绍

net/http包中提供了一个被称为Client的结构体,该结构体位于库文件的src/net/http/client.go文件中,常见使用场景一般是做go web开发过程中对接第三方的api接口(常见的比如微信授权获取手机号码等),爬虫领域的使用

Client这个结构体中已经帮我们实现了比较常见的GetPost请求,如果你要使用Delete等别的请求方式就要使用原生的http.NewRequest,其中GetPost只是官方帮我们封装了,底层还是使用的http.NewRequest来实现的

二、发送一个Get请求

这里使用微信官方比较常见的接口,获取accountToken

  • 定义返回的结构体

    // AccessTokenResponse 获取token的结构体
    type AccessTokenResponse struct {
    	AccessToken string `json:"access_token"` // token
    	ExpiresIn   int    `json:"expires_in"`   // 过期时间
    }
    
  • 简单的代码实现

    // GetAccessToken 根据appid和secret获取access_token
    func GetAccessToken(appId, secret string) string {
    	url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId, secret)
    	response, err := http.Get(url)
    	if err != nil {
    		fmt.println(fmt.Sprintf("获取access_token数据失败:【%s】", err.Error()))
    	}
    	defer func() {
    		if err1 := response.Body.Close(); err1 != nil {
    			return
    		}
    	}()
    	var result AccessTokenResponse
    	err = json.NewDecoder(response.Body).Decode(&result)
    	if err != nil {
    		fmt.println("获取access_token数据转码失败")
    	}
    	return result.AccessToken
    }
    

二、post请求

这里使用微信官方根据code获取手机号码的方式,后端小程序端

  • 1、第一步还是根据get的方式获取accountToken

  • 2、定义数据结构

    
    type MobileRequest struct {
    	Code string `json:"code"`
    }
    type PhomeWatermark struct {
    	Appid     string `json:"appid"`
    	Timestamp int64  `json:"timestamp"`
    }
    type PhoneInfoResponse struct {
    	CountryCode     string         `json:"countryCode"`
    	PhoneNumber     string         `json:"phoneNumber"`
    	PurePhoneNumber string         `json:"purePhoneNumber"`
    	Watermark       PhomeWatermark `json:"watermark"`
    }
    type MobileByCodeResponse struct {
    	ErrorCode int               `json:"errcode"`
    	Errmsg    string            `json:"errmsg"`
    	PhoneInfo PhoneInfoResponse `json:"phone_info"`
    }
    
  • 3、使用post发送请求到微信服务器端获取到手机号码

    // GetMobileByCode 根据code获取解密手机号码
    func GetMobileByCode(accountToken, code string) MobileByCodeResponse {
    	// 后端文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/phonenumber/phonenumber.getPhoneNumber.html
    	url := fmt.Sprintf("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s", accountToken)
    	mobileRequest := MobileRequest{
    		Code: code,
    	}
    	jsonBody, jsonErr := json.Marshal(mobileRequest)
    	if jsonErr != nil {
    		fmt.println("根据code获取手机号码失败")
    	}
    	response, err := http.Post(url, "application/json; charset=utf-8", bytes.NewReader(jsonBody))
    	if err != nil {
    		fmt.println("根据code获取手机号码,请求失败")
    	}
    	defer func(Body io.ReadCloser) {
    		err := Body.Close()
    		if err != nil {
    			fmt.println("根据code获取手机号码,关闭请求失败")
    		}
    	}(response.Body)
    	var mobileResponse MobileByCodeResponse
    
    	if err := json.NewDecoder(response.Body).Decode(&mobileResponse); err != nil {
    		fmt.println("根据code获取手机号码,解密失败")
    	}
    	fmt.Println(utils.MapToJson(mobileResponse), "查询结果")
    	return mobileResponse
    }
    

三、使用http.NewRequest发送post请求

这里使用创蓝发送短信来使用,参考地址

  • 简单的代码实现

    // SendSms 发送手机短信
    func (s Sms) SendSms(mobile, template string) error {
    	params := make(map[string]interface{})
    	//请登录zz.253.com获取API账号、密码以及短信发送的URL
    	params["account"] = s.Account   //创蓝API账号
    	params["password"] = s.Password //创蓝API密码
    	params["phone"] = mobile        //手机号码
    
    	//设置您要发送的内容:其中“【】”中括号为运营商签名符号,多签名内容前置添加提交
    	params["msg"] = url.QueryEscape(template)
    	params["report"] = "true"
    	bytesData, err := json.Marshal(params)
    	if err != nil {
    		fmt.Println(err.Error())
    		return errors.New(err.Error())
    	}
    	reader := bytes.NewReader(bytesData)
    	//短信发送URL
    	smsUrl := fmt.Sprintf("http://%s/%s", s.Host, "/msg/send/json")
    	request, err := http.NewRequest("POST", smsUrl, reader)
    	if err != nil {
    		fmt.Println(err.Error())
    		return errors.New(err.Error())
    	}
    	request.Header.Set("Content-Type", "application/json;charset=UTF-8")
    	client := http.Client{}
    	resp, err := client.Do(request)
    	if err != nil {
    		fmt.Println(err.Error())
    		return errors.New(err.Error())
    	}
    	var smsResponse = make(map[string]interface{})
    	err = json.NewDecoder(resp.Body).Decode(&smsResponse)
    	if err != nil {
    		fmt.Println("转码失败")
    		return errors.New(err.Error())
    	}
    	fmt.Println("发送短信结果", smsResponse)
    	if smsResponse["code"] == "0" {
    		return nil
    	} else {
    		// 接口数据类型断言成字符类型
    		message := smsResponse["errorMsg"]
    		result, _ := message.(string)
    		return errors.New(result)
    	}
    }
    
  • 上面发送短信的代码可以参考,使用go面向对象的方式来重写官方的代码

  • 对于其他的PUTDELETE使用方式和上面一样的

 类似资料: