解锁GoWeb核心理论

文章标题:

探索GoWeb的关键理论知识

文章内容:关于GoWeb,有一些你不可不知的知识

若你是初学者,可参考GoWeb来了解本文内容。

HTTP状态码:

意义

每一个状态码都是HTTP协议设计者针对网络通信中可能出现的情况所做的设想与预判。它就如同现实里的交通信号灯,当人们看到404状态码时,就知道资源无法找到;看到500状态码时,就明白服务器出现了故障。这种大家都能理解的共识,是如今万维网高效运作的重要基础之一。

HTTP状态码在日常开发和调试bug时是非常实用的工具。我们对常见的状态码进行了分类。

1、必须掌握的状态码

200 表示请求完全成功,这是最常见的状态码,比如打开网页、调用API等情况都会出现这个状态码。
301 代表资源被永久迁移(例如访问a.com时会被重定向到b.com)。
302 意味着部分资源临时迁移。
400 表示请求出错,可能是参数缺失等问题。
401 表示没有进行登录。
403 表示已经登录,但没有相应的权限。
404 表示请求的资源不存在。
500 表示服务器内部出现错误。

2、需要理解的状态码

在排查问题时经常会用到这些状态码。
100 表示继续。
201 表示资源创建成功(通常在POST请求后出现)。
204 表示处理成功,但不返回资源(一般在DELETE请求后出现)。
206 表示处理成功了一部分内容。
304 表示资源没有被修改,可以直接使用缓存。
405 表示请求的方法不被允许。
408 表示请求超时,也就是浏览器向服务器发送信息时超过了规定时间。
502 表示作为网关或代理时,接收到了无效的响应。
503 表示服务器暂时不可用,可能正在进行维护等操作(比如双十一时部分服务器可能出现这种情况)。

3、常用状态码集合
解锁GoWeb核心理论

HTTP协议

核心:
1、HTTP的本质

定义:超文本传输协议。
核心模型:是客户端发送请求、服务器进行响应的一问一答式信息传递模式。
无状态特性:服务器不会记住上一次的请求内容(后来通过引入Cookie、Session来解决这个问题)。
位置:HTTP协议处于应用层,规范了客户端和服务器之间的传输格式以及交互流程。

2、URL结构

例如:https://www.example.com:8080/path?name=test#fragment
* https:是所使用的协议类型。
* www.example.com:是域名,它对应着服务器的IP地址。
* 8080:是端口号,HTTP默认端口是80,HTTPS默认端口是443,这个端口号可以省略。
* /path:是资源的路径。
* ?name=test:是通过GET方法携带的参数来访问资源。
* #fragment:是锚点。

3、请求方法(Method)
  • GET:仅仅是请求获取资源,不会对服务器上的资源造成影响。
  • POST:用于提交数据,一般会在服务器上创建新的资源。
  • PUT:用于更新数据,如果没有对应的资源,就会新创建一个(和POST不同的是,PUT是幂等的)。
  • DELETE:用于删除数据(通常会返回204状态码)。
  • PATCH:用于修改部分资源(和PUT类似,但PUT是更新整个资源)。
4、状态码
  • 1xx 属于信息性状态码。
  • 2xx 表示请求成功。
  • 3xx 代表重定向。
  • 4xx 是客户端错误。
  • 5xx 是服务器错误。
进阶必备知识:
1、HTTP版本演进
  • HTTP/1.0:每次访问时,都会重新建立一个连接来请求URL。
  • HTTP/1.1:在HTTP/1.0的基础上,建立了持久化连接,但是只能串行地发送请求。
  • HTTP/2:可以实现多路复用,也就是在一个连接上同时发送多个请求,互不干扰。
  • HTTP/3:引入了UDP协议,解决了TCP头部堵塞的问题(特点是彻底摒弃了TCP协议,转而采用UDP协议)。
2、缓存机制
  • 强缓存:服务器通过设置Cache-Control: max-age=3600来告知浏览器,在1小时内访问该地址时,强制使用本地缓存(这就是为什么有时候修改了服务器资源后,客户端依然没有变化的原因,除非通过Ctrl+F5强制刷新)。
  • 协商缓存:如果强缓存过期了,浏览器在发送请求时会携带If-Modified-Since或者Etag,服务器会判断资源是否没有修改,如果没有修改就返回304状态码,让浏览器继续使用缓存。
3、HTTPS原理

https是由http和tls组合而成的。
核心区别:http是明文传输的,而https是http和tls的组合,数据会进行加密。
SSL/TLS的作用
就像一个“加密信封”,让HTTP数据更加安全:
1、加密:把明文数据(比如密码、订单信息等)转换成密文,即使被截获也无法破解。
2、身份认证:验证服务器的身份,防止是钓鱼网站。
3、完整性校验:确保信息没有被篡改。

4、Cookie 和 Session
  • Cookie:服务器通过set-cookie在客户端存储一些信息,用来解决HTTP协议无状态的问题。
  • Session:是服务器端存储的用户信息,与Cookie中的sessionid相关联。当用户登录时,服务器会向Cookie中设置sessionid,下次就可以通过这个sessionid在Session中找到相应的用户信息。
5、跨域资源共享(CORS)

跨域:由于同源策略(协议、域名、端口有任何一个不同,就不属于同一域)导致的不同源情况。
解决方法:服务器返回Access-Control-Allow-Origin响应头,允许指定域名的跨域请求。

Mysql的连接与增删改查

本篇是通过sqlx包来进行操作的,对数据库/sql操作进行了通用拓展,在保留原有基础功能的同时进行了加强。

连接
需要导入两个必要的包:
import(
    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"    
)
// 核心的两步:
DB,err := sqlx.Open("mysql","root:1234@tcp(localhost:3306)/goweb?parseTime=true&loc=Local");
DB.ping()
增删改查
// 语句
queryCreate:="insert into user (id,name) values (?,?) 
queryDelete:="delete from user where id =?"
queryUpdate:="update user set name=? where id=?;
queryQuery :="select * from user"
// 执行
增:DB.Exec(query,1,"白小纯")
删:DB.Exec(query,1)
改:DB.Exec(query,"夜藏",1)
查:rows,err:=DB.Query(query)
for rows.next() {rows.Scan(&id,&name)}

Cookie

起源:

cookie这个名字可不是随意起的,它源于unix中的 "magic cookie",也就是魔幻小饼干,是程序之间用于传递特定信息或状态的小数据包。
在1994年,被万景公司的一位天才程序员想到,当时是为了解决不让“电商”服务器承担过多消息的问题。后来因为它会悄悄记录用户信息,由于其“隐蔽跟踪”的本质,还引发了一时的大众恐慌。

应用:
后端的核心操作:
func serv(w http.ResponseWriter, r *http.Request) {
    // cookie赋值:
    cookie := &http.Cookie{
       Name:    "session_id",
       Value:   "cookie",
       Expires: time.Now().Add(time.Second),
    }

    http.SetCookie(w, cookie)
    // 获取单个cookie
    c, _ := r.Cookie("session_id")
    _, err := fmt.Fprintln(w, c.Name, c.Value, c.Expires)
    if err != nil {
       fmt.Println("...")
    }
    // 循环获取cookie
    cs := r.Cookies()
    for n, co := range cs {
       _, err = fmt.Fprintln(w, n, co.Name)
    }
}

template

模板的起源可以追溯到远古时代(最早可至3万年前),最初是为了批量生产特定物品而产生的。
在二十世纪八九十年代,C++因为泛型的需求引入了模板。后来在web领域,为了实现解耦也引入了模板。
而真正推动模板广泛应用的,是mvc架构的兴起,为了让控制器(control)和视图(view)彻底分离,模板引擎起到了关键作用。
简单来说,模板就是预制结构的文本,其中包含占位符和控制逻辑,通过模板引擎进行动态填充后生成最终的输出内容。

// 后端界面
func temp(w http.ResponseWriter, r *http.Request) {
    add := template.FuncMap{"add": Add}
    t := template.New("index").Funcs(add)
    t, _ = t.ParseFiles("new_add")
    t.Execute(w, nil)
}
// 前端
{{add 0 0}}

上传

是从浏览器向服务器传输数据的过程。

<form action="upload",enctype="multipart/form-data" method="post">
上传照片:<input type="file" name="photo">
<form>
func upload(w http.ResponseWriter, r *http.Request) {
    f, _, _ := r.FormFile("photo")
    b, _ := io.ReadAll(f)
    err := ioutil.WriteFile("/..",b,0777)
    if err!=nil{
       fmt.Println("失败")
    }
}

下载

<a href="download?filename=file.png">点击我下载</a>
func download(w http.ResponseWriter, r *http.Request) {
    name := r.FormValue("filename")
    ReadFile, _ := os.ReadFile("地址" + name)
    h := w.Header()
    h.Set("Content-Type", "application/octet-stream")
    h.Set("Content-Disposition", "attachment/filename=photo")
    fmt.Fprintln(w, ReadFile)
}

控制器

单控制器
type myStruct struct {}
func (m myStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
func main() {
    // 无论访问什么,结果都是一样
    s := http.Server{
       Addr:    "localhost:8888",
       Handler: myStruct{},
    }
}
多控制器
func Test(w http.ResponseWriter, r *http.Request) {}
func main() {
    // 无论访问什么,结果都是一样
    server:= http.Server{
       Addr: "localhost:8888",
    }
    http.HandleFunc("url", Test)
    server.ListenAndServe()
}

GET&POST核心区别类

一般需要重点关注get和post的本质区别(从语义、参数传递、幂等性、缓存等方面)。
语义:GET是用于获取资源,POST是用于提交资源。
参数:GET的参数在URL中,POST的参数在请求体里。
幂等性:GET多次执行结果不变(具有幂等性),POST可能多次提交(不具有幂等性,比如多次下单)。
缓存:GET容易被缓存,POST一般不被缓存。

版权声明:程序员胖胖胖虎阿 发表于 2025年8月6日 上午4:14。
转载请注明:解锁GoWeb核心理论 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...