前言
截止到目前为止,几乎我们的 Go 入门文章都是在终端运行的。
在终端运行的代码或者运用运用程序只适合自己在环境搭好的环境下使用。也就是说,如果用户没有安装 Go 语言环境,是根本没法运行我们所写的 Go 代码,普通用户可以说已经被互联网和万维网宠坏了,他们不想为了使用你的应用而学习使用终端。
更有甚者,不想在手机上安装任何多余的客户端和应用。他们希望能在浏览器解决的就能在浏览器上解决,单击某个链接或者扫个二维码就能使用。这大概也就是小程序——即用即走、无需安装的设计理念了吧。
用Go写Web应用
我们在终端上运行 Go 语言是这样的:
# yuzhou_1su @ RaindeMacBook-Pro in ~/GoProjects [22:23:34]
$ go run hello.go
hello, world
而在 Web 端运行一个 Go 程序可能是这样的:
net/http 包
Go 提供了非常方便的内置 http
包,涵盖了 HTTP 客户端和服务端的具体实现。使用 net/http
包,我们可以很方便地编写 HTTP 客户端或服务端的程序。
什么是 HTTP?
HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,定义了客户端和服务端之间请求与响应的传输标准。通过这种协议能够方便快捷的用于 Web 浏览器和 Web 服务器之间的通信。
具体的等我写到 HTTP 协议的时候的再说,目前只是简单的了解一下。
一个简单的 Web 应用程序
本来处理来自浏览器的请求需要做大量的工作:
- 接收来自浏览器的请求
- 对浏览器的请求进行响应
我们新建一个 main.go
文件,然后写入如下代码:
package main
import (
"log"
"net/http"
)
func viewHandler(writer http.ResponseWriter, request *http.Request) {
message := []byte("Hello, World!")
_, err := writer.Write(message)
if err != nil {
log.Fatal(err)
}
}
func main() {
http.HandleFunc("/hello", viewHandler)
err := http.ListenAndServe("localhost:8800", nil)
log.Fatal(err)
}
在终端中运行上述代码,这样我们就得到一个自己的 Web 应用程序:
$ go run main.go
此时在终端中不会看到任何输出,但是如果通过打开浏览器,输入服务器监听的地址:http://localhost:8800/hello
此时就是代表浏览器往我们的小型 Web 服务器发送了一个请求,然后服务器会响应一个 “Hello, World!” 作为响应。
如果此时,另开一个浏览器输入同一个网址,服务器会一直监听该请求,直到我们停止终端上运行的服务器,比如使用 CTRL+C
来退出我们的 main.go
函数:
$ go run main.go
^Csignal: interrupt
(base)
此时刷新该网址,再访问就会被拒绝,如下所示:
代码解释
看一段代码可以从 main
函数开始,代码解释如下:
http.HandleFunc("/hello", viewHandler)
使用了字符串/hello
调用http.HandleFunc
, 然后调用了viewHandler
函数,这段代码就是告诉应用程序每当收到以/hello
结尾的 URL 请求就调用viewHandler
函数- 调用
http.ListenAndServe("localhost:8800", nil)
来启动 Web 服务器,传入的字符串"localhost:8800"
表示只接受来自自己机器的 8800 端口上的请求。第二个参数nil
值只表示将使用 HandleFunc 设置得函数来稍后处理请求。 - 如果服务器没遇到错误,将会一直运行,知道遇到退出时,程序将记录该错误,并以错误日志输出该错误:
log.Fatal(err)
然后我们来看看 viewHandler
函数:
func viewHandler(writer http.ResponseWriter, request *http.Request)
- 服务器向
viewHandler
传递一个http.ResponseWriter
, 用于向浏览器响应写入数据 - 还接收一个指向
http.Request
指针,该值表示浏览器的请求 ResponseWriter
上的 Writer 方法响应添加数据,Writer 不接受字符串,但它能接收 byte 值得切片,所以在消息中message := []byte("Hello, World!")
将字符串“Hello, World!” 转换为[]byte
- 然后将转化好的
message
传递给 Writer - ResponseWriter 的 Writer 方法返回成功写入的字节数,以及遇到的任何错误,我们不能对写入的字节数做任何有用的事情,所以忽略它。如果出现错误,将会记录下来并退出程序。
总结
Web 应用程序需要做的第一件事就是当浏览器向 Web 服务器发送请求时能够做出响应。
而 Go 语言提供了很方便的 net/http
包来简化程序化的操作,使得我们无需写任何底层代码就能实现一个简易的 Web 应用。
但是,我们肯定不会止步于此,一个功能丰富的 Web 服务器不会仅仅是提供一个 “Hello,World!” 的访问,但是我们可以通过最简单的方式来了解 Web 开发。