Initial commit
This commit is contained in:
@@ -0,0 +1,318 @@
|
||||
# Web 基础架构
|
||||
|
||||
## 1. Web 类型
|
||||
|
||||
- **静态 Web**: 所有用户看到的内容完全相同
|
||||
- **动态 Web**: 根据用户身份、权限等展示不同内容
|
||||
|
||||
## 2. Web 应用架构
|
||||
|
||||
- **B/S (Browser/Server)**: 基于浏览器的 Web 应用
|
||||
- **C/S (Client/Server)**: 需要安装的客户端程序
|
||||
- 优势: 跨平台支持 (Windows/Mac/Linux)
|
||||
|
||||
## 3. 网络协议
|
||||
|
||||
- **HTTP**:
|
||||
- 标准端口: 80
|
||||
- 用途: 传输超文本(文本、图片、视频等)
|
||||
- **HTTPS**:
|
||||
- 标准端口: 443
|
||||
- 特点: 加密传输,更安全
|
||||
|
||||
## 4. 通信模型
|
||||
|
||||
**请求-响应模式**:
|
||||
- 请求 (Request):
|
||||
- 来源: 客户端(浏览器)
|
||||
- 内容: URL 地址(如 https://www.baidu.com)
|
||||
- 方式: GET、POST、PUT、DELETE 等
|
||||
- 响应 (Response):
|
||||
- 来源: 服务端
|
||||
- 功能: 处理请求并返回数据
|
||||
- 主要操作: CRUD(增删改查),占比约 80%
|
||||
|
||||
## 5. 工作流程
|
||||
|
||||
1. 客户端通过 TCP/IP 连接服务器
|
||||
2. 发送 HTTP(S) 请求:
|
||||
- 普通请求: www.example.com/login?username=xxx&pwd=xxx
|
||||
- 文件上传: upload/video?file=xxx
|
||||
3. 服务器处理请求
|
||||
4. 返回响应结果
|
||||
5. 客户端展示结果
|
||||
6. 断开连接
|
||||
|
||||
## 开发调试
|
||||
|
||||
- 使用浏览器开发者工具 (F12 或右键检查)
|
||||
- 分析请求/响应数据
|
||||
- 优化代码性能和健壮性
|
||||
|
||||
# helloworld
|
||||
|
||||
go 语言中所有和网络相关的都在 net 包下,http 也在 net 包下。
|
||||
|
||||
包含了客户端和服务端的代码实现。
|
||||
|
||||
未来我们学习的所有框架,都是基于这些底层代码的。
|
||||
|
||||
请求(request)- 响应(response)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// 一个简单的服务端代码实现
|
||||
// http程序启动之后是不会停止的,一直监听请求
|
||||
func main() {
|
||||
// 写一些请求来接收浏览器的信息
|
||||
// HandleFunc http请求的处理函数
|
||||
// func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
|
||||
// localhost:8080/hello url -> 代码处理
|
||||
http.HandleFunc("/hello", hello)
|
||||
|
||||
// 有一个地址给浏览器访问,什么都没有。404
|
||||
// func ListenAndServe(addr string, handler Handler)
|
||||
// localhost 本机(127.0.0.1) : 端口 (8080)
|
||||
// nil默认处理器,空的 404
|
||||
// 开启监听程序的代码是放在main方法的最后一行的。
|
||||
http.ListenAndServe("localhost:8080", nil)
|
||||
}
|
||||
|
||||
// 请求和响应
|
||||
func hello(resp http.ResponseWriter, req *http.Request) {
|
||||
// 查看一些请求信息 (/login:用户名和密码来匹配登录 /user/id 接收用户的id然后查询用户信息 )
|
||||
fmt.Println(req.URL)
|
||||
fmt.Println(req.Method)
|
||||
fmt.Println(req.RemoteAddr)
|
||||
//...
|
||||
|
||||
// 一般会响应一些信息给客户端 (文字、网页) resp.Write
|
||||
// 响应一段文字[]byte("hello,web")
|
||||
// 响应一段html代码 []byte("html代码") 网页
|
||||
resp.Write([]byte("<h1 style=\"color: red;\">hello,web</h1>"))
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
代码来写客户端
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// 手写客户端访问
|
||||
func main() {
|
||||
|
||||
/*
|
||||
http.Get()
|
||||
*/
|
||||
|
||||
// 请求方式 请求的url 接收响应结果
|
||||
resp, _ := http.Get("http://localhost:8080/hello")
|
||||
// 通过defer关闭连接 resp.Body 响应的主体
|
||||
defer resp.Body.Close()
|
||||
|
||||
fmt.Println(resp.Body)
|
||||
fmt.Println(resp.Status) // 200 OK
|
||||
fmt.Println(resp.Header) // 响应头
|
||||
|
||||
// 接收具体的响应内容
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
n, err := resp.Body.Read(buf)
|
||||
if err != nil && err != io.EOF {
|
||||
fmt.Println("读取出现了错误")
|
||||
return
|
||||
} else {
|
||||
fmt.Println("读取完毕")
|
||||
res := string(buf[:n])
|
||||
fmt.Println("服务器响应的数据为:", res)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# 带参数的请求
|
||||
|
||||
客户端编写
|
||||
|
||||
- url的参数拼接 ?拼接 & 连接
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 复杂请求
|
||||
urlStr := "http://127.0.0.1:8080/login" // ?
|
||||
// 参数如何拼接到url上,参数封装为数据url.Values{}
|
||||
data := url.Values{}
|
||||
data.Set("username", "admin") // ?
|
||||
data.Set("password", "123456") // ?
|
||||
// 将url字符串转化为url对象,并给携带数据
|
||||
urlNew, _ := url.ParseRequestURI(urlStr)
|
||||
urlNew.RawQuery = data.Encode()
|
||||
// http://127.0.0.1:8080/login?password=123456&username=kuangshen
|
||||
// ? get的传参,多个参数之间使用 & 连接
|
||||
fmt.Println(urlNew)
|
||||
|
||||
// 发请求,参数是一个地址
|
||||
resp, _ := http.Get(urlNew.String())
|
||||
defer resp.Body.Close()
|
||||
// 读取resp信息,返回buf
|
||||
buf, _ := io.ReadAll(resp.Body)
|
||||
fmt.Println(string(buf))
|
||||
}
|
||||
```
|
||||
|
||||
后台处理代码
|
||||
|
||||
```go
|
||||
func login(resp http.ResponseWriter, req *http.Request) {
|
||||
// 模拟数据库中存在一个数据
|
||||
mysqlUserData := "admin"
|
||||
mysqlPwdData := "123456"
|
||||
|
||||
fmt.Println("接收到了login请求")
|
||||
// 拿到请求中的参数
|
||||
urlData := req.URL.Query()
|
||||
username := urlData.Get("username")
|
||||
password := urlData.Get("password")
|
||||
|
||||
// 登录逻辑, 将客户端发送的数据和系统数据比对实现登录业务
|
||||
if username == mysqlUserData {
|
||||
if password == mysqlPwdData {
|
||||
resp.Write([]byte("登录成功"))
|
||||
} else {
|
||||
resp.Write([]byte("密码错误"))
|
||||
}
|
||||
} else {
|
||||
resp.Write([]byte("登录失败"))
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# 表单参数获取
|
||||
|
||||
html表单
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>登录</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!--表单-->
|
||||
<!--http://localhost:8080/register?username=kuangshen&password=123456-->
|
||||
<form action="http://localhost:8080/register" method="post">
|
||||
<h2>注册</h2>
|
||||
<p>用户名:<input type="text" name="username"></p>
|
||||
|
||||
<p>密码:<input type="password" name="password"></p>
|
||||
|
||||
<input type="submit" value="注册">
|
||||
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
后端处理代码
|
||||
|
||||
```go
|
||||
func register(resp http.ResponseWriter, req *http.Request) {
|
||||
fmt.Println("接收到了注册请求")
|
||||
// 处理表单的请求, 前端提交表单-后盾解析表单
|
||||
req.ParseForm() // 解析表单
|
||||
// 获取表单参数 post
|
||||
username := req.PostForm.Get("username")
|
||||
password := req.PostForm.Get("password")
|
||||
fmt.Println(username, password)
|
||||
// 很多的判断
|
||||
// 短信
|
||||
// 验证码
|
||||
resp.Write([]byte("注册成功"))
|
||||
}
|
||||
```
|
||||
|
||||
# 要给前端响应数据 (了解即可)
|
||||
|
||||
- 我们给前端数据
|
||||
- 页面模板要渲染数据!有很多语法,看看就好。类似于Java中的JSP 、或者PHP里面的代码
|
||||
- 代码+页面融合,很乱,已经被这个时代抛弃了
|
||||
- 前后端分离(我们后面都用这种方式)
|
||||
|
||||
1、通过代码跳转到页面 template
|
||||
|
||||
```go
|
||||
// 通过请求,进入页面(路由) temp.Execute(resp, data)
|
||||
// 通过URl进入某个页面
|
||||
func findAll(resp http.ResponseWriter, req *http.Request) {
|
||||
// 接收到前端的信息 /findAll, 查询全部用户
|
||||
userMap := make(map[int]User)
|
||||
userMap[1] = User{"KUANGSHEN", 1}
|
||||
userMap[2] = User{"xiaoming", 2}
|
||||
|
||||
// 返回给前端页面并渲染上去
|
||||
temp, _ := template.ParseFiles("./userlist.html")
|
||||
data := make(map[string](map[int]User))
|
||||
data["data"] = userMap
|
||||
temp.Execute(resp, data)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
2、前端的一些简答语法(了解即可,和php、jsp、C#差不多)
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>查询用户</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--获取后端的数据 {{.data}}
|
||||
遍历
|
||||
{{range $k,$v := .data}}
|
||||
|
||||
{{end}}
|
||||
|
||||
-->
|
||||
|
||||
{{range $k,$v := .data}}
|
||||
{{$k}}
|
||||
{{if eq $k 1}}
|
||||
{{.Name}}
|
||||
{{$v}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
Reference in New Issue
Block a user