美文网首页
Go-Web(请求响应篇)

Go-Web(请求响应篇)

作者: 秃头小公主 | 来源:发表于2020-11-17 17:15 被阅读0次

成功进入到了Go-Web开发的学习,个人感觉要是想快速上手,学完语法就可以看这个了,让后先不要直接学框架,很局限。就先开始简单的go-web,让后看到数据处理可以去看看gorm,基本上go-web就ok啦,来吧小秃头们,咱们继续肝~(文章适用于有go语言基础)
这一篇文章我们来说说与html的交互(我自己这么认为,不对就不对了),也就是说我们写代码来处理前端的那些事,一切响应的呈现会出现在前端。

——————————————————————————————————————

我会把我们比作控制器,前端就好比显示器,后台的数据就是需要展示的内容。我们需要经过这样的一个步骤:显示器(告诉我们需要什么)--->控制器(进行一些操作)--->显示器,其中控制器进行的一下操作就可能和数据库进行交互。下面我们来第一步:
在这里我们将熟悉使用GO语言的net/http标准库(就是import “net/http”)

1.接受请求(我们一步到位使用复用器,不用的编写放在最后)
当我们收到前端给我们的请求,这份请求先进入多路复用器让后找到相应的处理器(handler)进行处理之后响应给前端。吃栗子,上代码:

import (
    "encoding/json"
    "fmt"
    "github.com/gorilla/mux"
    "log"
    "net/http"
)

 func handler(w http.ResponseWriter,r *http.Request) {//这两个参数多眼熟啊,不需要介绍
    data:="mengyu"
    fmt.Printf("a")//这个会打印在你的goland里面
    json.NewEncoder(w).Encode(data)//简单来说就是data打印到页面上
                                   //json.NewEncoder(): io.writer 接口 json数据流的写 html显示
                                   //json.NewDecoder(): io.reader 接口 json数据流读
}
func main() {
    m:=mux.NewRouter() //来一个复用器
    m.HandleFunc("/",handler)//第一个参数:当输入地址后加/,让handler来处理(也就是上面的那个)
    ser:=&http.Server{
        Addr:"127.0.0.1:8000",//你需要输入的网址
        Handler: m,//什么使用的那个复用器(我感觉复用器也是一个handler)
    }
    log.Fatal(ser.ListenAndServe())//log.Fatal():1.打印输出内容 2.退出应用程序 3.defer函数不会执行
                                   //ListenAndServe():处理上面 端口监听、请求解析、路由分配、响应处理
}

完成上面的操作,就算我们的大方向搭建好了,这样你可以在你的handler里面处理一些操作等等(这个之后再说),当然我们也可以不使用复用器来搭建(这里鸽一下就不介绍了),下面我们来看一下handler的串联。对于handler有handler和handler函数这两个东西,我在这篇文章不做介绍,不懒我再写懒就继续鸽,这篇文章主要就是实用就完了(其实我感觉它俩差不多)吃栗子,上代码(handler串联):

func handler1(w http.ResponseWriter,r *http.Request)  {
    data:="mengyu"
    json.NewEncoder(w).Encode(data)
}

func handler2 (h http.HandlerFunc) http.HandlerFunc {
    return func(writer http.ResponseWriter, request *http.Request) {//这就是返回一个handler
        h(writer,request)
    }
}

func main(){
    m:=mux.NewRouter()
    m.HandleFunc("/",handler2(handler1))//串完之后从handler2再进入handler1
    ser:=&http.Server{
        Addr: "127.0.0.1:8000",
        Handler: m,
    }
    log.Fatal(ser.ListenAndServe())
}

以上就酱~,来看下一步

2.处理请求

一般遇到请求的就是,提交表单啊,上传文件什么的。来直接看怎么处理,理论啥的自行解决(来自实习生简单粗暴的怒吼)
(1)表单提交

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body><!--我们现拥有一个表单-->
<form action="//127.0.0.1:8000/hello?hello=world&thread=123"  method="post"
      enctype="application/x-www-form-urlencoded"><!--enctype:支持的编码方式,这种编码方式会把数据编码为一个连续的“长查询字符串”-->
    <input type="text" name="hello" value="mengyu">
    <input type="text" name="post" value="456">
    <input type="submit">
</form>
</body>
</html>
func handler(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()//对请求进行语法分析
    fmt.Fprintln(w,r.Form)//r.Form:包含所有请求的参数
}
func main() {
    m:=mux.NewRouter()
    m.HandleFunc("/",handler)
    ser:=&http.Server{
        Addr: "127.0.0.1:8000",
        Handler: m,
    }
    log.Fatal(ser.ListenAndServe())
}

(2)文件上传

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="//127.0.0.1:8000/hello?hello=world&thread=123" method="post"
      enctype="multipart/form-data"><!--这里enctype发生改变-->
    <input type="text" name="hello" value="mengyu">
    <input type="text" name="post" value="456">
    <input type="file" name="uploaded"><!--增加上传按钮-->
    <input type="submit">
</form>
</body>
</html>
func process(w http.ResponseWriter, r *http.Request) {
    file,_,err:=r.FormFile("uploaded") //FormFile():返回所提供表单的密钥的第一个文件
    if err==nil{
        data,err:=ioutil.ReadAll(file) //ReadAll():读取,直到出现错误或EOF,返回读取的数据
        if err==nil{
            fmt.Fprintln(w,string(data))
        }
    }
}

func main() {
    m:=mux.NewRouter()
    m.HandleFunc("/hello",hello)
    ser:=&http.Server{
        Addr: "127.0.0.1:8000",
        Handler: m,
    }
    log.Fatal(ser.ListenAndServe())
}

3.发送响应
直接吃点栗子
(1)用Write方法向客户端发送响应
HELLO会展示再html页面上

import (
    "github.com/gorilla/mux"
    "log"
    "net/http"
)

func writeExample(w http.ResponseWriter, r *http.Request) {
    str:="HELLO"
w.Write([]byte(str))
}

func main(){
    m:=mux.NewRouter()
    m.HandleFunc("/write",writeExample)
    ser:=&http.Server{
        Addr: "127.0.0.1:8000",
        Handler: m,
    }
    log.Fatal(ser.ListenAndServe())
}

(2)通过WriteHeader方法写状态
再写一个handler

func writeHeadExample(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(501)
    fmt.Fprintln(w,"ERROR:501")
}

再main中加入声明

m.HandleFunc("/writehead" ,writeHeadExample)

(3)通过编写首部实现客户端的重定向
再来一个handler

func headerExample(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Location" ,"https://www.jianshu.com" )//重定向到简书
    w.WriteHeader(302)//设置状态码
}

main中声明一下

m.HandleFunc("/redirect" ,headerExample)

4.Cookie
肯定有疑问,为什么这里放这么一个东西,这个东西干嘛的,来我们从头说~

  • 这个东西是伴随这客户端像服务器发送一个HTTP请求时候,cookie随着请求一起发送到服务器
  • 这个东西大概分两类:会话cookie和持久化cookie(其他知识请自行脑补)
  • 这个东西一般用来识别用户身份、记录历史(淘宝里面那个历史记录,估摸着就是他)

(1)将cookie发送到浏览器(将cookie存储到客户端)

func setCookie(w http.ResponseWriter,r *http.Request)  {
    c1:=http.Cookie{
        Name: "first_cookie",
        Value: "Go Web1",
        HttpOnly: true,
    }
    c2:=http.Cookie{
        Name:     "second_cookie",
        Value:    "Go Web2",
        HttpOnly: true,
    }
    http.SetCookie(w,&c1)//使用setCookie方法设置cookie
    http.SetCookie(w,&c2)

}

func main(){
    m:=mux.NewRouter()
    m.HandleFunc("/set_cookie",setCookie)
    ser:=&http.Server{
        Addr: "127.0.0.1:8000",
        Handler: m,
    }
    log.Fatal(ser.ListenAndServe())
}

(2)从浏览器获取cookie
加个handler

func getCookie(w http.ResponseWriter,r *http.Request)  {
    h:=r.Header["Cookie"]//先返回一个切片,切片中包含一个字符串,字符串中包含了好多cookie,
                         //让后再取得单独键值对格式cookie,这是一种很麻烦的方法来获取cookie
    fmt.Fprintln(w,h)
}

在main声明一下

m.HandleFunc("/get_cookie",getCookie)
  • 注意:先set再get,才会出现cookie,直接get没值

我们来换一个简单的方法来获取cookie

func getCookie(w http.ResponseWriter,r *http.Request)  {
    c1,err:=r.Cookie("first_cookie")//获取单个cookie
    if err!=nil{
        fmt.Fprintln(w,"error,don't get first_cookie")
    }
    cs:=r.Cookies()//获取所有的cookie
    fmt.Fprintln(w,c1)
    fmt.Fprintln(w,cs)
}

(3)cookie的应用——闪现消息
搜索网址出hello,刷新hello不见了~

import (
    "encoding/base64"
    "fmt"
    "github.com/gorilla/mux"
    "log"
    "net/http"
    "time"
)

func setMessage(w http.ResponseWriter,r *http.Request)  {
    msg:=[]byte("Hello")
    c:=http.Cookie{
        Name: "flash",
        Value: base64.URLEncoding.EncodeToString(msg),//对消息使用base64url编码,
         //(如果cookie的值没有“%” “ ”等特殊字符可以不编码),闪现消息本身会包含空格啥的,就得编码了
    }
    http.SetCookie(w,&c)
}
func showMessage(w http.ResponseWriter,r *http.Request)  {
    c,err:=r.Cookie("flash" )
    if err!= nil{//如果没有找到cookie
        if err == http.ErrNoCookie{
            fmt.Fprintln(w,"no message found!!!")  //把err变成一个http.ErrNoCookie值,并返回
                                              
        }
    }else {//如果找到了这个cookie
        rc:=http.Cookie{ //创建一同名cookie
            Name: "flash",
            MaxAge: -1, //设置过期时间(被浏览器创建之后存活多少秒)
            Expires: time.Unix(1,0),//设置过期时间为过去的时间(准确设置过期时间)
        }
        http.SetCookie(w,&rc)
        val,_:=base64.URLEncoding.DecodeString(c.Value)
        fmt.Fprintln(w,string(val))
    }
}
func main() {
    m:=mux.NewRouter()
    m.HandleFunc("/set_message",setMessage)
    m.HandleFunc("/show_message",showMessage)
    ser:=&http.Server{
        Addr: "127.0.0.1:8000",
        Handler: m,
    }
    log.Fatal(ser.ListenAndServe())
}

相关文章

  • Go-Web(请求响应篇)

    成功进入到了Go-Web开发的学习,个人感觉要是想快速上手,学完语法就可以看这个了,让后先不要直接学框架,很局限。...

  • 网络教程

    http协议包括 请求协议:请求行、请求头、请求体 响应协议:响应行、响应头、响应体 servlet

  • http协议

    http协议包含内容 请求 请求头 请求行 请求正文 响应 响应头 响应行 响应正文image.png

  • 接口测试(一)

    http协议内容 请求请求头请求行请求正文 响应响应头响应行响应正文 请求正文数据格式键值对XMLJSON 熟悉项...

  • HTTP请求和响应相关知识

    1.请求报文(请求行、请求头、请求体) 2.响应报文(响应行、响应头、响应体) 请求行、响应行比较简单,图上面也标...

  • kafka 网络模型2 Selector

    在上一篇文章中kafka 网络模型1 请求响应流程,我分析了Kafka的请求、响应流程,但留下了Selector的...

  • 2018-10-23 http协议与抓包

    一.http协议分为 1.请求(请求行,请求头,请求正文)2.响应(响应行,响应头,响应正文) 二.用Fiddle...

  • Gulu使用文档 - 目录

    1.请求: 请求类型 请求头 请求体 2.响应: 响应头 响应体 3.验证: 响应头验证 字符串验证 Json格式...

  • Day01-02

    请求报文 请求行+请求头+空行+请求体 响应报文 响应行+响应头+响应体 SEO 搜索引擎优化 DTD文档不是标签...

  • day10 以文章的为例的接口文档

    文章查询接口api 请求URL: 请求方式: 请求参数: 响应: 响应参数:

网友评论

      本文标题:Go-Web(请求响应篇)

      本文链接:https://www.haomeiwen.com/subject/wtlxiktx.html