web应用程序
web程序可以提供浏览器访问的程序。Web应用程序通常采用客户端-服务器模型。客户端是用户使用的Web浏览器或其他Web客户端,而服务器是存储和处理数据的远程计算机。
我们能访问到的任何一个页面或资源,都存在于世界的某一个角落的计算机上。
HTTP
HTTP(Hypertext Transfer Protocol)是一种用于传输超文本的协议,是Web上数据通信的基础。HTTP是一个客户端-服务器协议,客户端发起请求,服务器提供响应。
以下是HTTP的一些关键特点和基本概念:
无状态协议: HTTP是无状态的,即每个请求都是独立的,服务器不会保留前一次请求的任何信息。为了维护状态,通常使用会话(Session)机制或者使用Cookies。
请求和响应: HTTP通信由客户端的请求和服务器的响应组成。请求包括一个HTTP方法(GET、POST等)、URL、HTTP版本、请求头部和请求体。响应包括HTTP版本、状态码、响应头部和响应体。
URL(Uniform Resource Locator): URL是用于标识和定位资源的地址。它包括协议(如http://或https://)、主机名、端口号、路径和查询参数等。
HTTP方法: 常见的HTTP方法包括:
状态码: 服务器在响应中返回一个状态码,指示请求的处理结果。常见的状态码包括:
头部信息: HTTP请求和响应都包含头部信息,包括元数据、控制信息等。头部可以包括Content-Type、Content-Length、Cache-Control等。
持久连接: HTTP支持持久连接,可以在单个连接上发送多个请求和接收多个响应,以减少连接的开销。
安全性: HTTPS(HTTP Secure)是HTTP的安全版本,通过使用TLS/SSL协议对通信进行加密,以提供更安全的数据传输。
了解了web基础,我们尝试使用go语言的‘http’包,来模拟实现一个客户端-服务端的web应用。
//服务端代码
//server.go
package main
import (
"fmt"
"net/http"
)
func main() {
//请求处理
http.HandleFunc("/hello", hello)
http.ListenAndServe("127.0.0.1:8080", nil)
}
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL)
fmt.Println("有人访问了程序")
w.Write([]byte("heiheihei
"))
}
//hello
//有人访问了程序
//客户端代码
//client.go
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
resp, err := http.Get("http://127.0.0.1:8080/hello")
if err != nil {
fmt.Println(111, err)
}
defer resp.Body.Close()
buf := make([]byte, 1024)
for {
n, err := resp.Body.Read(buf)
if err != nil && err != io.EOF {
fmt.Println(err)
return
} else {
fmt.Println("信息读取完毕")
fmt.Println("data", string(buf[:n]))
break
}
}
}
//信息读取完毕
//data heiheihei
我们模拟一个登录过程,看看go语言中如何处理请求参数。
//server.go
package main
import (
"fmt"
"net/http"
)
func main() {
//请求处理
http.HandleFunc("/login", login)
http.ListenAndServe("127.0.0.1:8080", nil)
}
func login(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL)
data := r.URL.Query()
username := data.Get("username")
password := data.Get("password")
fmt.Println(username, password)
if username == "admin" {
w.Write([]byte("{status:ok}"))
} else {
w.Write([]byte("{status:fail}"))
}
}
//admin 123456
上面的服务端代码中,解析get中的query参数,并判断用户进行登录。
//client.go
package main
import (
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
urlStr := "http://127.0.0.1:8080/login"
data := url.Values{}
data.Set("username", "admin")
data.Set("password", "123456")
rurl, _ := url.ParseRequestURI(urlStr)
rurl.RawQuery = data.Encode()
fmt.Println(rurl.String())
resp, _ := http.Get(rurl.String())
b, _ := io.ReadAll(resp.Body)
fmt.Println(string(b))
}
//{status:ok}
上面的客户段模拟代码中,拼接参数,并向服务端发送请求。通过io解析响应流。
//服务端
package main
import (
"fmt"
"net/http"
)
func main() {
//请求处理
http.HandleFunc("/register", register)
http.ListenAndServe("127.0.0.1:8081", nil)
}
func register(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fmt.Println(111, r.ParseForm())
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")
fmt.Println(username, password)
oUsername := "admin"
if oUsername == username {
w.Write([]byte("{msg:'用户已存在'}"))
} else {
w.Write([]byte("{msg:'用户注册成功'}"))
}
}
通过PostForm来解析post请求携带的数据
通过以上的学习。我们基本了解了Go语言如何实现客户端-服务端之间的通信交互。后续将会继续探索数据库及一些成熟go语言web框架。来快速搭建和编写web服务器,存储数据。