成功进入到了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())
}
网友评论