
关于goweb,你不得不知道的知识
若是初学者可以借鉴GoWeb查阅本文。
每个状态码都是,http设计者对“网络通讯”中可能出现的情况的假设、预判。他就相当于现实世界的信号灯,就像大家一遇到404,就知道资源找不到了。一遇到500就知道服务器挂了。这种共识,也就是如今万维网的高效率的基础之一。
http状态码是日常开发,修改bug,的居家必备神器。咱们对常见状态码做了分类。
200 ok 最常见的状态码,代表请求完全正确,比如打开网页、调用api啥的。
301 moved permanently 资源永久迁移(例:访问时a.com会被从定项到b.com)
302 Found (部分资源,临时迁移)
400 Bad request(请求出错,参数缺少什么的..)
401 unauthorized(没有登入)
403 forbidden(登入了,没权限)
404 not found(资源不存在)
500 internal server error(服务器内部错误)
排查问题时常用
100 continue
201 created 资源创建成功(POST..
204 not content 处理成功,但不返回资源(DELETE..
206 partial content(处理成功了一部分..
304 not modified(资源没有修改,可以直接用缓存)
405 method and allow(方法不被允许)
408 request time-out(请求超时,浏览器向服务发送信息)
502 bad gateway(作为网关/代理时,收到无效相应)
503 service unavailable(服务器暂不可用,正在维修...双十一)

定义:超文本传输协议
核心模型:【请求+响应】 客户端发送请求、服务器响应,一问一答的进行传递信息
无状态:服务器不会记住上一次请求(后期引入了Cookie、Session)
位置:HTTP协议存放在应用层,规范 (客户端-服务器) 的传输格式、交互流程。
比如:https://www.example.com:8080/path?name=test#fragment
https=http+tls
核心区别:http是明文传输、https是http+tls组合,数据会加密。
SSL/TLS的作用:
像"加密信封",让HTTP数据更安全: 1、加密:把明文数据(如密码、订单信息)变成密文,及时被截获也无法破解。 2、身份认证:验证服务器的身份,防止是钓鱼网站。 3、完整性校验:确保信息没有被篡改。
跨域:来自同源策略(协议、域名、端口有个不同,就不属于同一域)
解决:服务器返回 Access-Control-Allow-Origin 响应头,允许指定域名的跨域请求。
本篇是通过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的名字可不是随便起的,他源于unix中的 "magic cookie",魔幻小饼干 --- 程序之间用于传递特定信息或状态的小数据包。
被万景公司的天才程序员,于1994年,在解决不让 “电商” 服务器承担更多消息时,灵光一现想出来的东西。
后来也因为悄悄记录了用户信息,因cookie“隐蔽跟踪”的本质,而引起了一时的大众恐慌。
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)
}
}模板起源于远古时代(最早至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是参数在URL,POST在请求体
幂等性:GET多次执行结果不变(幂等),POST可能多次提交(非幂等、多次下单)
缓存:GET易被缓存、POST一般不缓存
借鉴博客:
1、GoWeb开发