Go 标准库之 GoRequests 介绍与基本使用

文章目录

    • 一、介绍
    • 二、安装
    • 三、导入
    • 四、基本使用
      • 4.1 发送GET 请求
      • 4.2 POST请求发送JSON数据
      • 4.3 Post 文件上传
      • 4.4 GoRequests 使用代理
      • 4.5 Gorequests 使用session
    • 五、HTTP服务端代码

一、介绍

官方文档 DOC: https://pkg.go.dev/github.com/levigross/grequests

Github: http://github.com/levigross/grequests

Python中的Requests库非常强大,所以Go开发者模仿Python的Requests库,由此诞生了Grequests库。Grequests提供了一系列便利功能,使得发送HTTP请求变得简单高效。下面就是Grequests在Golang中实现的一些关键特性:

  • 响应序列化Grequests支持将HTTP响应内容序列化为JSON和XML格式,让处理API响应时更为方便。
  • 文件上传和下载:提供了便捷的方式来上传和下载文件,无需复杂的配置。
  • HTTP动词支持:支持广泛的HTTP动词,包括GET、HEAD、POST、PUT、DELETE、PATCH以及OPTIONS,可以覆盖大多数HTTP请求场景。

二、安装

要开始使用Grequests库,你需要先在你的Go环境中安装它。通过下面的命令即可完成安装:

go get -u github.com/levigross/grequests

三、导入

在安装完Grequests后,你可以通过import语句把它引入到你的Go代码中:

import "github.com/levigross/grequests"

四、基本使用

4.1 发送GET 请求

下面是一个发送GET请求的示例,其中演示了如何获取HTTP响应并打印出来:

func Get() {resp, err := grequests.Get("http://127.0.0.1:8080/book/", nil)if err != nil {log.Fatalln("Unable to make request: ", err)}if !resp.Ok {log.Fatalln("请求超时!")}// 解析响应的JSON数据var data []map[string]interface{}if err := resp.JSON(&data); err != nil {log.Fatalln("Unable to parse JSON response: ", err)}fmt.Println(data)
}

上面的代码首先使用Get方法发送GET请求,然后检查是否有错误发生。如果没有错误,就可以通过resp.Json()方法获取响应的文本内容。

4.2 POST请求发送JSON数据

在下面的例子中,我们创建了一个map对象来保存我们想要发送的JSON数据。然后我们通过ROption创建了一个请求选项对象,并在其中指定了JSON为发送的数据类型。最后,我们调用Post方法来发送请求:

func Post() {postData := map[string]string{"id":   "1","name": "Go入门到进阶",}geq := &grequests.RequestOptions{JSON: postData,}resp, err := grequests.Post("http://127.0.0.1:8080/book/create", geq)if err != nil {log.Fatalln("Unable to make request: ", err)}fmt.Println(resp.String())
}

下面是代码的逐行解释:

  1. postData := map[string]string{"id": "1", "name": "Go入门到进阶"}
    • 这里定义了一个map[string]string类型的变量postData,其中包含了两个键值对,分别是"id"和"name",它们的值分别是"1"和"Go入门到进阶"。
  2. geq := &grequests.RequestOptions{JSON: postData}
    • 这里创建了一个grequests.RequestOptions类型的变量geqgrequests.RequestOptions是一个结构体,用于配置HTTP请求的各种选项,如URL、方法、头信息、数据等。在这个例子中,我们通过JSON字段将postData作为JSON数据传递给POST请求。
  3. resp, err := grequests.Post("http://127.0.0.1:8080/book/create", geq)
    • 这里调用grequests.Post函数发起一个POST请求。http://127.0.0.1:8080/book/create是请求的目标URL,而geq是请求的配置选项。grequests.Post函数会返回一个Response对象和一个可能的错误。
  4. if err != nil { log.Fatalln("Unable to make request: ", err) }
    • 如果grequests.Post函数调用时发生错误,这个条件块会执行。log.Fatalln函数会打印错误消息并退出程序。
  5. fmt.Println(resp.String())
    • 如果请求成功,这个条件块会执行。resp.String()方法会返回响应体的字符串表示,然后使用fmt.Println函数将其打印到标准输出。
      总的来说,这段代码的作用是向本地服务器(假设在127.0.0.1:8080上)的/book/create路径发送一个POST请求,请求体是JSON格式的数据,包含一个ID和书名。如果请求成功,它会打印出服务器的响应。如果请求失败,它会打印出错误信息并退出程序。

4.3 Post 文件上传

文件上传同样简单。你可以通过RequestOptions指定文件:

func UploadFile() {// 允许您通过指定磁盘上的位置来创建FileUpload结构片// 打开要上传的文件file, err := os.Open("./go.mod")if err != nil {log.Fatalln("Unable to open file: ", err)}defer file.Close()// 创建FileUpload结构片ro := &grequests.RequestOptions{Files: []grequests.FileUpload{{FileName:     "1.txt", // 上传后的文件名称FieldName:    "file",  // 上传文件对应字段FileContents: file, // 使用文件内容作为FileContents}},}// 发送POST请求resp, err := grequests.Post("http://127.0.0.1:8080/book/upload/", ro)if err != nil {log.Fatalln("Unable to make request: ", err)}fmt.Println(resp.String())
}

在上述代码中,我们创建了一个FileUpload结构,通过FileNameFieldNameFileContents来指定我们要上传的文件详情。

4.4 GoRequests 使用代理

gorequest代理,下面是一个简单的例子,需要把Proxies中的URL添加为*url.URL代理:

func Proxy() {// 代理服务器const proxyServer = "http-pro.xxx.com:9010"// 代理隧道验证信息const proxyUser = "xxxxxxxxx"const proxyPass = "xxxxxxxxx"// 初始化代理URLproxyUrl, _ := url.Parse("http://" + proxyUser + ":" + proxyPass + "@" + proxyServer)// 创建请求选项ro := &grequests.RequestOptions{Proxies: map[string]*url.URL{"http": proxyUrl,},Headers: map[string]string{"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",},}// 发起GET请求resp, err := grequests.Get("http://www.example.com", ro)if err != nil {fmt.Println("Error:", err)return}// 打印响应状态码fmt.Println("Status code:", resp.StatusCode)// 打印响应体fmt.Println("Response:", resp.String())
}

下面是代码的逐行解释:

  1. // 代理服务器
    • 这一行是一个注释,声明了接下来的代码将定义代理服务器的URL。
  2. const proxyServer = "http-pro.xxx.com:9010"
    • 这里定义了一个常量proxyServer,它的值是代理服务器的URL,格式为http://host:port
  3. // 代理隧道验证信息
    • 这一行是一个注释,声明了接下来的代码将定义代理隧道的验证信息。
  4. const proxyUser = "xxxxxxxxx"
    • 这里定义了一个常量proxyUser,它的值是代理隧道的用户名。
  5. const proxyPass = "xxxxxxxxx"
    • 这里定义了一个常量proxyPass,它的值是代理隧道的密码。
  6. // 初始化代理URL
    • 这一行是一个注释,说明接下来的代码将创建代理URL。
  7. proxyUrl, _ := url.Parse("http://" + proxyUser + ":" + proxyPass + "@" + proxyServer)
    • 这行代码使用url.Parse函数创建了一个代理URL。它将代理隧道的用户名、密码和代理服务器地址组合成一个URL,格式为http://username:password@host:port_是忽略返回值的约定,因为返回值通常不需要使用。
  8. // 创建请求选项
    • 这一行是一个注释,说明接下来的代码将创建一个grequests.RequestOptions结构体,用于配置HTTP请求。
  9. ro := &grequests.RequestOptions{
    • 这里开始定义grequests.RequestOptions结构体变量ro
  10. Proxies: map[string]*url.URL{
    • 这里定义了Proxies字段,它是一个映射,将协议(如"http")映射到代理URL。
  11. "http": proxyUrl,
    • 这行代码将代理URL设置为HTTP协议的代理。
  12. },
    • 这是映射定义的结束。
  13. Headers: map[string]string{
    • 这里定义了Headers字段,它是一个映射,将HTTP头字段(如"user-agent")映射到相应的值。
  14. "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
    • 这行代码设置了一个HTTP头字段,即用户代理(User-Agent),用于标识发起请求的客户端。
  15. },
    • 这是映射定义的结束。
  16. }
    • 这是grequests.RequestOptions结构体变量的定义结束。
  17. // 发起GET请求
    • 这一行是一个注释,说明接下来的代码将发起一个GET请求。
  18. resp, err := grequests.Get("http://www.example.com", ro)
    • 这行代码使用grequests.Get函数发起一个GET请求。http://www.example.com是请求的目标URL,而ro是请求的配置选项。grequests.Get函数会返回一个Response对象和一个可能的错误。
  19. if err != nil {
    • 如果grequests.Get函数调用时发生错误,这个条件块会执行。
  20. fmt.Println("Error:", err)
    • 这行代码打印出错误信息。
  21. return
    • 这行代码表示如果发生错误,函数将返回,不继续执行。
  22. }
    • 这是错误处理块的结束。
  23. fmt.Println("Status code:", resp.StatusCode)
    • 如果请求成功,这行代码会打印出响应的状态码。
  24. fmt.Println("Response:", resp.String())

4.5 Gorequests 使用session

下面是使用Session的一个例子:

session := grequests.Session{RequestOptions: &grequests.RequestOptions{Headers: map[string]string{"authority":  "mp3.haoge500.com","referer":    "https://www.zz123.com/","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",},},}

五、HTTP服务端代码

package mainimport ("encoding/json""github.com/gin-gonic/gin""net/http""os"
)type Book struct {ID   string `json:"id"`Name string `json:"name"`
}type BookHandler struct {
}func (b *BookHandler) RegisterRoutes(server *gin.Engine) {bg := server.Group("/book")bg.POST("/upload", b.Upload)bg.POST("/create", b.Create)bg.GET("/", b.GetAllBooks) // 查询书籍
}func (b *BookHandler) Upload(ctx *gin.Context) {// 从请求中获取文件file, err := ctx.FormFile("file")if err != nil {ctx.JSON(http.StatusBadRequest, gin.H{"error": "无法获取上传的文件"})return}// 将文件保存到服务器// 注意:这里需要确保保存文件的目录存在,并且服务器有写入权限savePath := "./uploads/" + file.Filenameif err := ctx.SaveUploadedFile(file, savePath); err != nil {ctx.JSON(http.StatusInternalServerError, gin.H{"error": "文件保存失败"})return}ctx.JSON(http.StatusOK, gin.H{"message": "文件上传成功"})
}func (b *BookHandler) Create(ctx *gin.Context) {var req Bookif err := ctx.Bind(&req); err != nil {return}// 将新的书籍数据保存到data.json文件中if err := addBookToFile(&req); err != nil {ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save book data"})return}ctx.JSON(http.StatusOK, gin.H{"message": "Book added successfully"})
}
func (b *BookHandler) GetAllBooks(c *gin.Context) {// 从data.json文件中读取书籍数据books, err := getBooksFromFile()if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read book data"})return}// 获取URL查询参数中的idid := c.Query("id")// 如果提供了ID,查找具有匹配ID的书籍列表if id != "" {// 查找具有匹配ID的书籍var foundBooks []Bookfor _, book := range books {if book.ID == id {foundBooks = append(foundBooks, book)}}// 如果找到了匹配的书籍,返回这些书籍if len(foundBooks) > 0 {c.JSON(http.StatusOK, foundBooks)return}// 如果没有找到匹配的书籍,返回404c.JSON(http.StatusNotFound, gin.H{"error": "Books not found"})return}// 如果没有提供ID,返回所有书籍c.JSON(http.StatusOK, books)
}
func addBookToFile(book *Book) error {// 读取现有的data.json文件内容var books []Bookdata, err := os.ReadFile("data.json")if err != nil && !os.IsNotExist(err) {return err}// 如果文件存在,解析现有的书籍数据if err == nil {if err := json.Unmarshal(data, &books); err != nil {return err}}// 将新的书籍添加到数组中books = append(books, *book)// 将更新后的书籍数组序列化为JSONnewData, err := json.MarshalIndent(books, "", "    ")if err != nil {return err}// 将序列化的JSON数据写入data.json文件if err := os.WriteFile("data.json", newData, 0644); err != nil {return err}return nil
}
func getBooksFromFile() ([]Book, error) {// 读取data.json文件内容data, err := os.ReadFile("data.json")if err != nil {return nil, err}// 解析JSON数据到书籍数组中var books []Bookif err := json.Unmarshal(data, &books); err != nil {return nil, err}return books, nil
}func InitWebServer(bookHandler *BookHandler) *gin.Engine {server := gin.Default()bookHandler.RegisterRoutes(server)return server
}func main() {// 确保上传目录存在os.MkdirAll("./uploads", 0755)bookHandler := &BookHandler{}server := InitWebServer(bookHandler)server.Run(":8080") // 在8080端口启动服务器
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python系列】非异步方法调用异步方法

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

echars点击图例之后只显示当前数据其他隐藏

1. 确认echarts默认效果 echarts默认点击图例有如下效果: 当前图例显示,点击后隐藏该图例;当前图例隐藏,点击后显示该图例。 2. 确认需要处理的事件 经过在官网查看事件后发现最合适的是legendselectchanged事件,该…

C语言学习/复习23---

一、数据的存储 二、数据类型的介绍 三、整型在内存中的存储 将原码转换为补码。如果数是正数,则补码与原码相同;如果数是负数,则先将原码按位取反,然后加1。将补码转换原补码。如果数是正数,则补码与原码相同&#x…

【简单介绍下日常的启发式算法】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

CLSRSC-400: A system reboot is required to continue installing

RHEL 7.9ORACLE RAC 12.2.0.1.0,在运行root.sh脚本时,出现CLSRSC-400: A system reboot is required to continue installing报错 # /u01/app/12.2.0/grid/root.sh Performing root user operation.The following environment variables are set as:ORA…

Python中实现类似MATLAB的常用技巧

在Python中实现类似MATLAB的常用技巧,主要依赖于NumPy、SciPy、Matplotlib等库。以下是一些常用的技巧和最佳实践: 1. 矩阵和数组操作: - 使用NumPy进行高效的矩阵运算。例如,利用广播机制进行数组间的算术运算,使用np.dot或操…

在Windows安装R语言

直接安装R语言软件 下载网址:R: The R Project for Statistical Computing 下载点击install R for the first time 通过Anaconda下载RStudio 提前下载好Anaconda 点击Anaconda Navigate 点击RStudio的Install下载就好了

《大话数据结构》04 静态链表

1. 静态链表 其实C语言真是好东西,它具有的指针能力,使得它可以非常容易地操作内存中的地址和数据,这比其他高级语言更加灵活方便。后来的面向对象语言,如Java、C#等,虽不使用指针,但因为启用了对象引用机…

JWT和网关双令牌登录验证

使用JWT(JSON Web Token)和网关实现双令牌登录验证是一种安全性较高的方案。双令牌通常包括一个短期有效的访问令牌(access token)和一个长期有效的刷新令牌(refresh token)。以下是如何在Spring Boot项目中…

C语言进阶课程学习记录-第36课 - 函数与指针分析

C语言进阶课程学习记录-第36课 - 函数与指针分析 函数类型实验-函数指针实验-回调机制小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 函数类型 实验-函数指针 #include <stdio.h>typedef in…

PLC工业网关,实现PLC联网

在当今工业自动化领域&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为控制系统的核心&#xff0c;其稳定性和可靠性至关重要。然而&#xff0c;随着工业互联网和智能制造的快速发展&#xff0c;如何实现PLC的联网通信&#xff0c;提高数据传输效率&#xff0c;成…

[蓝桥杯 2023 省 A] 更小的数(dp基础应用)

来源 洛谷P9232 本题dp思想 dp主要思想是&#xff1a;在同一类问题模型下&#xff0c;依赖于已经解决的简单问题基础上&#xff0c;用很小的代价获得更复杂一点的问题的解决方案。 有的题的DP是在下标上顺序性递推的&#xff0c;类似于dp[i]dp[i-1]something&#xff1b; 然…

Redis教程——数据类型(哈希、集合)

上篇文章我们学习了Redis教程——数据类型&#xff08;字符串、列表&#xff09;&#xff0c;这篇文章学习Redis教程——数据类型&#xff08;哈希表、集合&#xff09; 哈希表Hash 哈希表是一个string类型的field(字段)和value(值)的映射表&#xff0c;hash特别适合用于存储…

C语言进阶课程学习记录-函数指针的阅读

C语言进阶课程学习记录-函数指针的阅读 5个标识符含义解析技巧 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 5个标识符含义解析 int (*p1) (int* , int (*f) ( int* ) );定义了指针p1,指向函数&#…

OpenHarmony实战开发-如何通过分割swiper区域,实现指示器导航点位于swiper下方的效果。

介绍 本示例介绍通过分割swiper区域&#xff0c;实现指示器导航点位于swiper下方的效果。 效果预览图 使用说明 1.加载完成后swiper指示器导航点&#xff0c;位于显示内容下方。 实现思路 1.将swiper区域分割为两块区域&#xff0c;上方为内容区域&#xff0c;下方为空白区…

采用等价类划分法设计测试用例

例题1 请采用等价类划分法设计测试用例。 考虑软件 app, 它有两个输入变量 , 分别是 name 和 age, 其中 ,name 是至多包含 20 个字母字符的非空字符串 ,age 是整数型变量 ,0 ≤ age ≤ 120 。当输入给 name 的字符串的长度超过 20时 ,name 取前 20 个字符作为 name 的值 ; 如果…

【面试经典 150 | 二分查找】搜索旋转排序数组

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;二分查找 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行…

清理prometheus监控历史数据

# 18、清理prometheus&#xff08;监控&#xff09;历史数据 转至元数据起始 现象&#xff1a;1.监控大盘主机&#xff0c;/data磁盘使用率100% 2.开发者中心首页所有主机显示“未添加监控”&#xff1b; 思路&#xff1a;1.缩短prometheus的监控数据保存期限&#xff08;平…

宏集eX700M系列HMI实现港口设备数据上云

前言 随着港口设备信息化技术的快速发展&#xff0c;越来越多的企业想要把现场设备数据上传到云平台&#xff0c;进而实现关键数据的远程监控和分析处理。在此背景下&#xff0c;国内某信息化公司想要将港口设备数据通过MQTT上传到该公司自研IOT平台&#xff0c;实现数据上云&…

DDD学习

概述 学习一下DDD 什么是DDD DDD是领域驱动设计&#xff08;Domain Driven Design&#xff09;的缩写&#xff0c;是一种软件开发方法论。它强调将业务领域划分为多个紧凑的、自包含的领域&#xff0c;并通过强调领域模型的重要性来建立一个通用的语言和理解。 DDD鼓励开发…