go web 学习第二天 笔记备忘

HTTP 请求

1.Request请求
2.URL
3. Header
4.Body

HTTP Request 和 HTTP Response(请求和响应)

他们具有相同的结构:
请求(响应)行
0个或者多个Header
空行
可选的消息体(Body)

Request (是个struct) 代表了客户端发送得 HTTP 请求消息
重要字段:URL Header Body Form PostForm MultiparForm
也可以通过Request 的方法访问请求的 Cookie URL User Agent 等信息

Request 即可代表服务器请求,又可以代表客户端发送的请求。

Request 的URL 字段代表请求行(请求信息第一行) 里边的部分内容

URL字段是指向 url.URL类型的一个指针, url.URL 是一个结构体

URL的通用形式: scheme://[userinfo@]host/path[?query][#fragment]
不可以斜杠开头的 URL会被解释成 : scheme:opaque[?query][#fragment]

URL Query 会提供实际查询的字符串
例如:HTTP://www.example.com/post?id=123&thread_id=456

URL Fragment 详细信息

如果从浏览器发出的请求,那么你无法提取出Fragment 字段值。(鸡肋现在没啥卵用)

Request Header

请求和响应(Request Response) 的 Header是通过 类型来描述,他是一个map,用来表述HTTP Header 里的Key-value对

Header Map 的Key是string类型 Value是[]string 切片

设置key 的时候就会创建一个空的[]string 作为 value ,其中的第一个值就是新的header值。
为指定key添加一个新的header 值,执行append操作即可。

Request Header 例子
1 r.header 返回map
2 r.Header[“key”] 返回[]string 切片
3 r.Header.Get(key) 返回时string 结果集用 逗号 隔开

Request Body

请求和响应的bodies 都是使用Body 字段来表示
Body是一个io.ReadCloser接口
一个Reader接口
一个Closer接口

Reader 接口定义了一个Open 方法
参数:[]byte
返回: byte的数量,可选错误

Closer 接口定义了一个Close方法
没有参数,返回值可选的错误。

4.1 查询参数(Query Parameters)

URL Query: 例如:HTTP://www.example.com/post?id=123&thread_id=456

r.URL.RawQuery 会提供实际查询的原始字符串
上面的例子得到的数值: id=123&thread_id=456

r.URL.Query() 会提供查询字符串对应的map[string] []string

4.2 通过表单发送请求

Form 字段

简单文本: 表单URL编码
大量数据,例如上传文件:multipart-mime
甚至可以把二进制数据通过Base64 编码,当做文本进行发送

表单Get请求没有Body 所有数据都是通过URL 的name-value 对发送
Request 上的函数准许我们从URL或者 Body 中提取数据,通过这些字段
Form
PostForm
MultipartForm
Form 里边的数据是key-value 对
通常的做法是:
先调用ParseForm或者ParseMultipartForm来解析Request
然后在响应的访问Form PostForm MultipartForm

PostForm字段
只取表单里边的数据,忽略url里边请求的信息。

以上的两个字段都可以使用r.ParseForm() 进行数据解析,解析表单应该是这种类型enctype="application/x-www-form-urlencoded"  如果是其他类型应当慎重解析

MultipartForm 字段
对应表单的提交方式应该为: enctype=“multipart/form-data” 解析方式应该对应为:r.ParseMultipartForm(r.ContentLength)
第二个参数是数据长度。
MultipartForm 只包含表单的key-value
返回类型是一个struct 而不是map 这个struct有两个map

FormValue 和PostFormValue 方法
FormValue 方法会返回Form 字段中指定Key 对应的第一个value
无需先调用ParseForm 或者ParseMultipartForm
PostFormValue 方法也是一样,但只能调取PostForm
但是如果表单enctype 设置为 Multipart / form-data 那么即使你调用PostFormValue获得想要的值

文件(Files)

上传文件:Multipart/form-data 常见的应用场景就是长传文件(例子)
	首先调用ParseMultipartForm 方法
	从File字段 获得FileHeader ,调用其Open方法获取文件
	可以使用ioutil.ReadAll 函数把文件内容读取到byte 切片里

如果调用 FormFile 方法可以不用先不用调用 r.ParseMultipartForm(r.ContentLength)
file,_,err := r.FormFile(key值)

例子;
package main

import (
“fmt”
“io/ioutil”
“net/http”
)

func main() {
http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(r.ContentLength)
fileHeader := r.MultipartForm.File[“upload”][0]
file, err := fileHeader.Open()
if err == nil {
data, err := ioutil.ReadAll(file)
if err == nil {
fmt.Fprintln(rw, string(data))
}
}

	fmt.Fprintln(rw, r.MultipartForm)
})
http.ListenAndServe(":8081", nil)

//http.ListenAndServe(":8081", http.FileServer(http.Dir("www4399")))

}

网页示例:

测试窗体

Post JSON
不是所有的POST 请求都来自From
客户端框架(例如:Angular等) 会以不同的方式对Post请求解码;
jQuery 通常使用 application/x-www-form-urlencoded
Angular 是Application/json
ParseForm 方法无法处理 application/json

5.1 Form-MultipartReader()
方法签名:func(r *Request) MultipartReader()(*multipart.Reader ,error)
如果是 Multipart/form-data 或 Multipart 混合的post请求
否则返回nil 和一个错误
可以使用该函数代替ParseMultipartForm 来吧请求的Body 作为 Stream 进行处理
它不是把表单作为一个对象来处理,不是一次性获得整个map
逐个检查来自表单的值,然后每次处理一个。

  1. ResponseWrite
    从服务器向客户端返回响应需求要使用ResponseWriter
    ResponseWrite 是一个接口,handler用他来返回响应
    真正支撑ResponseWrite 的幕后Struct 是非导出的http.response
    一个有趣的问题
    为什么Handler 的ServerHTTP(rw ResponseWrite ,r *Request),只有一个指针类型?而rw是按值传递
    答:实际rw实际也是指针类型,也是引用传递

写入到ResponseWrite
Write 方法接收一个byte 切片作为参数 然后把它写到HTTP 响应的Body 里面
如果在Write 方法被调用时, header 里边没有用设定content type ,那么数据前512 字节就会被用来检测 content type
例子:

package main

import (
“net/http”
)

func writeExple(rw http.ResponseWriter, r *http.Request) {
str := “测试窗体

新年好啊!!!


rw.Write([]byte(str))
}

func main() {
server := http.Server{
Addr: “localhost:8081”,
}

http.HandleFunc("/write", writeExple)
server.ListenAndServe()

}

WriteHeader 方法
WriteHeader 方法接收一个整数类型(HTTP 状态码) 作为参数,并把它作为HTTP 响应的状态码返回
如果该方法没有显示调用,那么在第一次调用Write 方法前,会隐士的调用WriteHeader(http.StatusOK)
所以WriteHeader 主要用来发送错误类型的HTTP状态码
调用完WriteHeader 方法后,仍然可以写入到ResponseWrite
但是无法在修改header了

例子:
package main

import (
“encoding/json”
“fmt”
“net/http”
)

func writeExple(rw http.ResponseWriter, r *http.Request) {
str := “测试窗体

新年好啊!!!


rw.Write([]byte(str))
}

func writeHeadExample(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(501)
fmt.Fprintln(rw, “不作死就不会死!no 咗 no 待”)
}

func headExample(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set(“Location”, “http://baidu.com”)
rw.WriteHeader(302)
}

func jsonExample(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set(“Content-Type”, “application/json”)
data := &myData{
User: “王天发”,
Threads: []string{“你是谁”, “你爸爸”, “马飞飞”},
}
rJsonBts, _ := json.Marshal(data)
rw.Write(rJsonBts)
}

type myData struct {
User string
Threads []string
}

func main() {
server := http.Server{
Addr: “localhost:8081”,
}

http.HandleFunc("/write", writeExple)
http.HandleFunc("/writeHead", writeHeadExample)
http.HandleFunc("/headSet", headExample)
http.HandleFunc("/json", jsonExample)
server.ListenAndServe()

}

内置 Response
NotFound 函数,包装一个404 状态码和一个额外的信息
ServerFile 函数,从文件系统提供文件,返回给请求者
ServerContent 函数,他可以把是实现了io.ReadSeeker 接口的任何东西里边的内容返回给请求者
还可以处理Range请求(范围请求) 如果只请求了资源的一部分内容,那么ServeContent 就可以如此响应,而 ServerFile 或io.Copy则都不行
Redirect 函数,告诉客户端重定向另外一个URL

——————————————————————————————————————————————

模板部分主要内容
简介
Web模板就是先设计好的HTML 页面,他可以被模板引擎反复的使用,来产生HTML页面
Go的标准库提供了 text/template html/template 两个模板库
大多数Go的Web框架都使用这些库作为默认模板引擎

模板引擎
	可以合并模板与上下文数据,最终的HTML
	两种理想模板引擎
		无逻辑模板引擎:通过占位符,动态数据被替换到模板中。不做任何逻辑处理,只做字符串替换,处理完全由handler来完成。目标是展示层和逻辑的完全分离。
		逻辑嵌入模板引擎:编程语言被嵌入到模块中,在运行时由模板引擎来执行,包含替换功能,功能强大,逻辑代码遍布handle和模板  难以维护。
		
	Go的模板引擎
		主要用的是 text/template , HTML 相关部分使用了 html/template 是个混合体
		模板可以完全无逻辑,但是又具有足够的嵌入特性。
		和大多数模板引擎一样,Go Web的模块位于无逻辑和嵌入之前的某个地方。
	Go的模板引擎工作原理
		在web应用中,通过是由handler来触发模板引擎
		handler 调用模板引擎,并将使用的模板传递给引擎(通常是一组模板文件和动态数据)
		模板引擎生成HTML,并将其写入到ResponseWrite 
		ResponseWriter 再将它加入到HTTP 响应中,返回给客户端

关于模板
	模板必须是可读文本格式,扩展名任意,对于Web 应用通常是HTML 
		里边会嵌入一些命令(叫做action)
	text/template 是通用模板引擎, html/template 是HTML模板引擎
	action 位于双层花括号之间: {{.}}
		这里的. 就是一个action 

使用模板引擎
	解析模板源(可以是字符串或模板文件),从而创建一个解析好的模块的 struct
	执行解析好的模板,并传入ResponseWriter 和数据
		这会触发模板引擎组合解析好的模板和数据,来产生最终的HTML 并将它传递给ResponseWriter
	例子:
	func processExample(rw http.ResponseWriter, r *http.Request) {
	t, _ := template.ParseFiles("index.html")
	t.Execute(rw, "Hello 你好啊 (*´▽`)ノノ")
	}

Action
参数,变量,管道
函数
模板组合

解析模板
ParseFile
解析模板文件,并创建一个解析好的模板 struct 后续可以被执行
ParseFile 函数是Template struct上ParseFiles 方法的简单调用
调用ParseFiles后,会创建一个新的模板,模板名字是文件名
New 函数
ParseFiles 的参数数量可变,但只返回一个模板
当解析多个文件时,第一个文件作为返回的模板(名,内容),其余的作为map 供后持续执行使用

ParseGlob
	使用模式匹配来解析特定的文件
Parse

Must函数
	可以包裹一个函数,返回到一个模板的指针 和一个错误 
		如果错误不为 nil 那么就panic 
执行模板
	Execute:参数是 ResponseWrite 数据。  单模板:很实用。 模板集: 只用第一个模板
	ExecuteTemplate: 参数: ResponseWriter 模板名  数据。 模板集: 很适用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

望天hous

你的鼓励是我最大动力~谢谢啦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值