本文是作者自己学习goweb时写的笔记,分享给大家,希望能有些帮助
前言:
关于web:本质
web中最重要的就是浏览器和服务器的request(请求)和response(响应);
一个请求对应一个响应。
一个请求对应一个响应!
一个请求对应一个响应!
一个请求对应一个响应!
路由请求方式:GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH,ANY
gin
原理讲解
package main
import "github.com/gin-gonic/gin" //导包
func Hello(c *gin.Context) {
//gin.Context是gin框架的上下文,封装了request(请求)和response(响应)
//里边是对页面的渲染效果,即给浏览器响应什么内容,可以是string的内容,也可以是json的内容,也可以是html的内容
c.String(200, "这是我的第一个gin框架程序")
}
func main() {
//Default返回一个默认的路由引擎Engine,他是框架非常重要的数据结构,是框架的入口,
//所有的注册路由都是在这个结构体上进行的,所以在使用gin框架时,一定要先初始化一个Engine
//引擎-框架核心发动机-默认服务器,整个web服务都由它驱动
//Default底层调用了New(),相当于定义的升级版,多加了中间件-engine.Use(Logger(),Recovery())
r := gin.Default()
//r := gin.New()
//路由:通过访问"/"的GET请求,来执行后面的匿名函数
//前面“/”是路由规则,后边是路由函数,是一个协程
//路由请求方式:GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH,ANY
r.GET("/", func(c *gin.Context) {
c.String(200, "这是我的第一个gin框架程序")
})
//或 写成 r.GET("/", Hello)
//启动引擎,服务器启动传入host+port,默认8080端口
r.Run(":8080")
}
最基础的路由创建和绑定
传字符串和结构体
主函数:
func main() {
r := gin.Default()// 创建引擎
//加载文件
r.LoadHTMLGlob("templates/**/*")//指定目录
//加载静态文件
r.Static("/s", "static") //指定静态文件目录s是真实目录static
r.GET("/demo01", myfunc.Hello)
//r.GET("/Hello", Hello)
r.Run(":8080")
}
方法函数:
package myfunc
import "github.com/gin-gonic/gin"
type Student struct {
Name string `json:"name"`
Age int `json:"age"`
}
func Hello(c *gin.Context) {
//name := "你好我是姗姗老师"//string类型文件
c.HTML(200, "demo01/hello01.html", name)//string类型文件传入
c.HTML(200, "demo01/hello01.html", Student{Name: "张三", Age: 18})
//结构体类型文件传入
}
HTML文件:
{{define "demo01/hello01.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="s/css/mycss.css">
</head>
<body>这是hello01.html文件,欢迎使用模板引擎
<span>这部分我想要使用红色</span>
//{{.}}
{{.Name}}
</body>
</html>
{{end}}
渲染数组:
模板文件:
或
渲染结构体类型的数组:
渲染Map类型
页面模板获取
渲染入了多个结构体类型的map
第三个参数
模板文件格式
.代表上下文的map即a,.no1通过key得到value,再.Name就是通过value得到具体结构体字段
渲染切片
传入切片:
模板文件格式:
可以看出来和数组格式一样
企业级路由文件封装
主函数:
import (
"awesomeProject1/demo/router"
)
func main() {
r:=router.Router()
err := r.Run(":8080")
if err != nil {
return
}
}
router文件
package router
import "github.com/gin-gonic/gin"
func Router() *gin.Engine {//user目录下的请求全都放到这个文件里,看这更清晰
r := gin.Default()
user := r.Group("/user")
{
user.POST("/list", func(c *gin.Context) {
c.String(200, "user add")
})
user.PUT("/add", func(c *gin.Context) {
c.String(200, "user add")
})
user.DELETE("/delete", func(c *gin.Context) {
c.String(200, "user delete")
})
}
return r
}
最后返回r
响应
响应(Response)是Web应用程序向客户端发送的数据,用于传递请求处理的结果或内容。在HTTP协议中,响应是服务器端向客户端发送的数据,它包含了一个HTTP状态码、响应头部和响应主体(body)。
以下是响应的主要作用和组成部分:
- 传递请求处理结果:
- 响应用于向客户端传递服务器对客户端请求的处理结果。这可能包括请求的成功或失败,以及相关的数据或信息。
- HTTP状态码:
- HTTP状态码是响应的一部分,用于指示请求的处理状态。常见的状态码包括200(成功)、404(未找到)、500(服务器内部错误)等。状态码提供了关于请求处理的重要信息。
- 响应头部:
- 响应头部包含了与响应相关的元信息。这些信息包括内容类型(Content-Type)、内容长度(Content-Length)、响应时间等。响应头部帮助客户端正确解释响应主体。
- 响应主体:
- 响应主体是响应的核心部分,包含了实际的数据、内容或信息。它可以是HTML网页、JSON数据、图像、文本等,具体内容取决于响应的类型和用途。
- 告知客户端如何处理响应:
- 响应头部中的内容类型(Content-Type)指示了响应主体的数据类型。这使得客户端能够正确解析和处理响应数据。
- 控制缓存和缓存有效性:
- 响应头部中的缓存控制指令可以告知客户端和中间代理服务器如何缓存响应以及响应的有效期。这有助于提高性能并减少不必要的网络请求。
---------------------------响应string
func _string(c *gin.Context) {
//返回字符串
c.String(200, "你好阿")
//状态码,200表示正常响应
}
func main() {
router := gin.Default()
//router.GET("/", _string)
err := router.Run(":80")
if err != nil {
return
}
}
、、、、、、、、、、、、、、、、、、响应json、、、、、、、、、、、、、、、、
func _json(c *gin.Context) {
type UserInfo struct {
UserName string `json:"user_name"`
Age int `json:"age"`
Password string `json:"-"`
}
user := UserInfo{"峰峰", 20, "123456"}
c.JSON(200, user)
}
func main() {
router := gin.Default()
//router.GET("/", _string)
router.GET("/", _json)
err := router.Run(":80")
if err != nil {
return
}
}
json最常用,其他很少用到;
在golang中么有相对路径,只有相对项目的路径
重定向:(网页跳转)
router.GET("/redirect", func(c *gin.Context) {
//支持内部和外部的重定向
c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")
})
//redirect指字节写的网址,后边是跳转到什么网址
301 Moved Permanently
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
302 Found
请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
请求
请求(Request)是Web应用程序或客户端向服务器发出的一种行为,用于获取特定资源、执行操作或与服务器交互。请求的主要作用是向服务器发送请求以获取所需的数据、执行操作或与服务器进行通信。以下是请求的主要作用和组成部分:
- 获取资源:
- 请求可以用于获取服务器上的特定资源,例如网页、图像、视频、文档等。通过发送HTTP请求,客户端可以向服务器请求所需的资源,然后服务器会响应并将资源发送回客户端。
- 执行操作:
- 请求还可以用于执行特定的操作或命令。例如,通过HTTP POST请求,客户端可以向服务器提交表单数据,服务器会处理这些数据并采取相应的操作,如创建新记录、更新数据等。
- 与服务器通信:
- 请求还用于与服务器进行实时通信。WebSocket请求是一种实时通信协议,客户端和服务器可以通过WebSocket建立持久的双向通信通道,以便在不刷新页面的情况下进行实时更新和交互。
- 提供数据:
- 请求可以用于向服务器提供数据。通过HTTP PUT或HTTP POST请求,客户端可以将数据传递给服务器,服务器可以对这些数据进行处理、存储或分析。
- 传递请求参数:
- 请求通常包含请求参数,这些参数用于指定请求的细节和要求。例如,GET请求中的查询字符串参数、POST请求中的表单数据、HTTP头部中的信息等。
- 控制请求类型:
- 请求还可以用于控制请求的类型和行为。例如,HTTP请求方法(GET、POST、PUT、DELETE等)和HTTP头部可以用于指定请求的类型、内容类型、授权信息等。
请求通常由客户端(例如浏览器、移动应用程序)发起,然后由服务器进行响应。服务器根据请求中的信息和操作执行相应的逻辑,并将响应返回给客户端,以完成请求的目标。
请求和响应的关系
- 请求(Request):
- 请求是由客户端(例如浏览器、移动应用程序)发送到服务器的消息,用于获取特定资源、执行操作或与服务器交互。
- 请求包含了客户端的需求和指令,以告诉服务器它希望获取什么资源,执行什么操作,或传递什么数据。
- 请求通常包括HTTP请求方法(如GET、POST、PUT、DELETE等)、请求头部(包括内容类型、授权信息等)、URL路径和查询参数等信息。
- 响应(Response):
- 响应是服务器对客户端请求的回应,用于传递请求处理的结果、资源数据或其他信息。
- 响应包括了HTTP状态码(例如200表示成功、404表示未找到、500表示服务器内部错误等)、响应头部(包括内容类型、缓存控制等)以及响应主体(包含实际数据或内容)。
- 响应的目的是将请求处理的结果传递给客户端,以便客户端可以理解和使用这些数据或信息。
web标准的通信流程:
- 请求(Request):客户端(通常是浏览器或应用程序)发起一个请求,以获取特定资源、执行操作或与服务器交互。这个请求包括了客户端需要的信息,如请求的方法(GET、POST、PUT、DELETE等)、URL、请求头部和请求主体(如果有的话),还可能包括查询参数、请求体数据等。
- 服务器处理请求:一旦服务器接收到请求,它会根据请求中的信息,执行相应的操作。这可能包括检索数据库、处理业务逻辑、生成响应内容等。
- 响应(Response):服务器处理完请求后,会生成一个响应,包括一个 HTTP 状态码(表示请求的成功或失败)、响应头部(包含关于响应的元信息)、响应主体(包含实际的数据或内容)。服务器将响应发送回客户端。
- 客户端处理响应:客户端接收到服务器的响应后,会根据响应内容执行相应的操作,例如渲染页面、显示数据、执行进一步的操作等。
查询参数:Query
func _query(c *gin.Context) {
fmt.Println(c.Query("user")) //拿到单个查询参数
fmt.Println(c.GetQuery("user")) //判断是否查询成功
fmt.Println(c.QueryArray("user")) //拿到多个查询参数
}//?user=张三&user=王五 查询参数
动态参数:Param
func _param(c *gin.Context) {
fmt.Println(c.Param("user_id"))
fmt.Println(c.Param("book_id"))
}
func main() {
router := gin.Default()
router.GET("/param/:user_id/", _param)
router.GET("/param/:user_id/:book_id", _param)
router.Run(":80")
}
//?param/12
?param/12/123
表单参数:PostForm
func _form(c *gin.Context) { //表单,请求表单,表单参数
fmt.Println(c.PostForm("name"))
fmt.Println(c.PostFormArray("name"))
fmt.Println(c.DefaultPostForm("addr", "四川省"))
//没传设置默认值
forms, err := c.MultipartForm() //接收所有form参数,包括文件
fmt.Println(forms, err)
}
原始参数:GetRawData
四大请求方式
以文字为例:
// 以文字资源为例
// GET /articles 文章列表 查
// GET /articles/:id 文章详情 查
// POST /articles 添加文章 增
// PUT /articles/:id 修改某一篇文章 改
// DELETE /articles/:id 删除某一篇文章 删
一脸懵逼,先接着看
请求头相关
请求头参数获取
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"strings"
)
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
//首字母大小写不区分,单词与单词之间用 - 连接
fmt.Println(c.GetHeader("User-Agent"))
//Header是一个普通的string
fmt.Println(c.Request.Header)
c.JSON(200, gin.H{"msg": "成功"})
})
router.GET("/index", func(c *gin.Context) {
userAgent := c.GetHeader("User-Agent")
//用正则去匹配
//字符串的包含匹配
if strings.Contains(userAgent, "python") { //爬虫来了
c.JSON(0, gin.H{"data": " 这是响应给给爬虫的数据"})
return
}
c.JSON(0, gin.H{"data": ""})
})
router.Run(":80")
}
gin项目结构
├── conf #项目配置文件目录
│ └── config.toml #大家可以选择自己熟悉的配置文件管理工具包例如:toml、xml等等
├── controllers #控制器目录,按模块存放控制器(或者叫控制器函数),必要的时候可以继续划分子目录。
│ └── user.go
├── models #模型目录,负责项目的数据存储部分,例如各个模块的Mysql表的读写模型。
│ ├── food.go
│ └── user.go
├── static #静态资源目录,包括Js,css,jpg等等,可以通过Gin框架配置,直接让用户访问。
│ ├── css
│ ├── images
│ └── js
├── logs #日志文件目录,主要保存项目运行过程中产生的日志。
└── views #视图模板目录,存放各个模块的视图模板,当然有些项目只有api,是不需要视图部分,可以忽略这个目录
│ └── index.html
├── main.go #项目入口,这里负责Gin框架的初始化,注册路由信息,关联控制器函数等。
未完,以后会更新的