在上一节中,我们创建了一个简单的Http服务器,通过在浏览器输入http://127.0.0.1:8000/ ,就看到了网页输出的Hello World了。那这个请求是如何发生的呢?下面我们打开Chrome浏览器,使用右键,选择检查,可以调出Chrome的开发者工具。
下面我们选择其中的Network,并且重新刷新一下网页,我们可以看到中间多了两个请求。
其中第一个是获取网页内容的请求,第二个是获取网页图标的请求。我们点击第一个,可以看到访问的请求,以及数据包。
这里可以看到,我们“General”、“Request Headers”、“Response Headers”这三项,其中“General”显示了一些基本的信息,比如说请求的地址“Request URL”,请求的方法“Request Method”,请求的响应码“Status Code”。
其中请求的方法主要包括Get和Post,Get方法就是我们平时查看网页时候使用的方法,它把请求的参数和内容放在网址中,直接就能看到。而POST则是我们登录、上传文件使用的方法,它把请求的参数放在请求头中,需要通过抓包工具才能看到。本教程在接下来的案例中只会使用到GET方法,有关POST的东西读者可以自行查阅相关资料。
响应码代表着服务器返回的状态,比如说:200代表成功,302代表网址跳转,404代表没有找到相应资源,500代表服务器内部的错误。读者可以在相关的百度百科查阅
请求的网址就不用多说了,下面我们看一下请求头(Request Headers)和响应头(Response Headers)。
首先看看请求头,可以通过点击“view source”查看原始的请求头。
可以看到,第一行使用了GET请求,请求网站的“/”地址,使用HTTP1.1版本的协议。接下来的是一些键值对,比如说Host代表请求的服务器地址,User-Agent代表浏览器的版本信息,其他的读者可以自行百度查阅。
类比可以看到,第一行返回了HTTP协议的版本,以及响应码200和响应信息OK。接下来的键值对代表了返回的一些基础信息,时间(Date),内容长度(Content-Length),内容的类型(Content-Type)。
在了解了HTTP请求,下面使用telnet这个tcp客户端来模拟一下HTTP请求。我们打开dos界面,首先输入“telnet”查看是否开启了这个命令。
Windows默认是禁用telnet的,所以我这里找不到。我们打开控制面板,选择“程序与功能”。
开启之后,我们重新打开
dos界面,输入“telnet”回车之后,就可以看到命令生效了。
我们关闭当前终端,重新打开个dos终端。下面我们要模拟HTTP请求了,首先要运行5.3节的http_server.go,让服务器跑起来。我们连接的是本地的8000端口,先输入
telnet 127.0.0.1 8000
输入之后,就可以看到进入了一个空白窗口。此时摁下ctrl键 + ']' 键进入输入模式,然后再按回车切换到显式输入模式。
此时我们仿照这用Chrome抓下来的数据,输入"GET / HTTP/1.1[回车]Host:localhost[回车回车]"如下,我们就可以看到输出的“Hello World”了。
了解了Http请求之后,我们再来说说gin这个框架,虽然我们能在go语言提供的API已经能完成一个网页的显示了,但是通过一些框架,我们可以更容易的完成它,缩短开发的时间。go语言的web框架很多,gin是其中一个我觉得比较简单、易用、性能高的go语言web框架,而且在git上比较活跃,目前(2017年3月2日)已有9000多个star数了。
在此之前,我们并没有实战过如何安装go语言的第三方包。
在这里我们需要用到之前下载好的GitHub客户端提供的Git Shell
。我们先打开Git Shell,然后输入git
命令确定是否能使用git。
这里可以看到输出了git的使用说明。在这里,我们不能直接打开dos窗口,因为它会提示git命令找不到。
下面就是安装过程了,我们使用go get
命令,输入go get github.com/gin-gonic/gin
即可完成安装。
等待片刻,即可完成安装。
有的时候,我们会依赖到一些访问不到的包,如:“golang.org/x/net/html”,这种情况,你可以去第三方包下载的网站如:https://gopm.io下载第三方包,输入包名,然后手动导入到$GOPATH里面的src中。
安装好了gin,我们开始先跑一个HelloWorld。
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(200, "Hello World")
})
r.Run(":8000")
}
运行之后,访问可以看到一些debug信息,比如下面是向“/”发送了两次GET请求。
不过Windows上的显示并不是很友善,如果你在Mac或者Ubuntu下,将看到很友好的Debug信息。
Web的路由就是访问不同的网址可以获取不同的结果,相应的,我们在代码中对不同的网址需要用不同的函数来处理。这里的不同的网址指的并不是网址完全不同,而是形式不同,比如说一个查询温度的,我们可以通过city参数来获取不同城市的温度,而不用为每个不同的城市都编写一个函数来查询它的温度。
在gin中,有两种方式获取,一种是queryString,一种是直接在url的path中获取。我们通过一个查询温度的案例来学习一下,代码见下方:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
//通过queryString
r.GET("/temp", func(c *gin.Context) {
city := c.DefaultQuery("city", "") //获取city参数,默认为""
responseTemp(city, c)
})
//通过path
r.GET("/temp2/:city", func(c *gin.Context) {
city := c.Param("city")
responseTemp(city, c)
})
r.Run(":8000")
}
func responseTemp(city string, c *gin.Context) {
temps := map[string]string{
"北京": "23℃",
"上海": "20℃",
"哈尔滨": "11℃",
}
if temp, ok:= temps[city]; ok {
c.String(200, "%s的温度是:%s", city, temp)
} else {
c.String(200, "没找到%s的温度", city)
}
}
这两种方式都是可以的,queryString可以通过“ http://localhost:8000/temp?city=北京 ”访问,而path可以通过“ http://localhost:8000/temp2/北京 ”访问。
HTML渲染是将模板中的变量、表达式等等做替换,然后转换成HTML再给浏览器。
我们先来看一个最简单的模板引擎,下面的HTML模板中引入了一个变量title,我们可以通过传递title参数,然后模板通过解析"{{ }}",并对变量进行替换,然后显示相应的结果。
<html>
<h1>
{{ .title }}
</h1>
</html>
除了变量以外,还有各种表达式(if、for),下面以上面查询天气的接口为例子,先创建一个templates目录,并创建temp.tmpl。
填写我们温度查询的模板。
<html>
{{if .temp}}
<h1>{{ .city }}的温度是:{{ .temp }}</h1>
{{ else }}
<h1>没有找到{{ .city }}的温度</h1>
{{ end }}
</html>
编写代码:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.LoadHTMLGlob("./templates/*")
r.GET("/temp/:city", func(c *gin.Context) {
city := c.Param("city")
temps := map[string]string{
"北京": "23℃",
"上海": "20℃",
"哈尔滨": "11℃",
}
if temp, ok:= temps[city]; ok {
c.HTML(200, "index.tmpl", gin.H{
"city": city,
"temp": temp,
})
} else {
c.HTML(200, "index.tmpl", gin.H{
"city": city,
})
}
})
r.Run(":8000")
}
除了一些动态资源外,编写网站还需要图片资源,这里我们比如说把静态资源都放在static目录下面。(如果读者没有学习过HTML、CSS、JS的话可以跳过此部分)
我们创建好static下面的css、js目录,然后准备我们的测试文件。
style.css:
body {
background-color: #eee;
}
main.js:
alert("js 测试");
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>静态文件测试</title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<h1>静态文件测试</h1>
<script src="/static/js/main.js"></script>
</body>
</html>
最后使用gin的StaticFS方法就可以构建静态文件系统
r.StaticFS("/static", http.Dir("./static"))
运行程序,可以看到js代码执行后显示出了提示框,以及body的背景也变成了灰色。
- 目录
- 上一节:用go语言显示一个网页
- 下一节:部署go语言项目