Go Web编程 第四章--处理请求
请求和响应
Request结构
- URL字段
- Header字段
- Body字段
- Form, PostForm, MultipartForm字段
在处理器函数中,我们可以通过Request获取各个字段的详细信息
func get_request_value(w *http.ResponseWriter, r *http.Request) {
h := r.Header
brower := r.Header.Get("User-Agent")
fme.Fprintln(w, h)
body := make([]byte, r.ContentLength)
r.Body.Read(body)
fmt.Fprintln(w, string(body))
}
Go与HTML表单
用户在表单中输入的数据会以键值对的形式记录在请求的主体中,其中表单中的enctype属性决定了以何种形式发送键值对。默认属性值为application/x-www-form-urlencoded,这个属性会把表单中的数据编码一个连续的长查询字符串,另一种编码方式为multipart/form-data,表单中的数据会被转换为一条MIME报文,每个键值对都构成了这个报文的一部分。简单来说,当表单只需要传送简单数据时,默认编码更加简单,高效;而当表单需要传输大量数据(如文件)时,使用后一种编码方式会更好。有些时候,用户可以通过Base64编码,以文本方式传送二进制数据。
使用Request结构获取表单数据的一般步骤是:
- 调用ParseForm或者ParseMultipartForm方法进行语法分析
- 访问Form, PostForm, MultipartForm等字段获取数据
func get_form_data1(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fmt.Fprintln(w, r.Form)
// PostForm字段只支持默认编码,并且只返回表单值,不返回URL查询值
fmt.Fprintln(w, r.PostForm)
}
当使用multipart/form-data编码时,表单数据会被存储到MultipartForm字段中
func get_form_data2(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(1024)
fmt.Fprintln(w, r.MultipartForm)
}
我们也可以使用FormValue或者PostFormValue快速获取表单值,也两个方法会自动调用ParseForm或者ParseMultipartForm方法,其中PostFormValue只会返回表单键值对而不会返回URL键值对
使用FormFile方法可以快速的获取被上传的文件
func process(w http.ResponseWriter, r *http.Request) {
file, _, err := r.FormFile("upload")
if err == nil {
data, err := ioutil.ReadAll(file)
if err == nil {
fmt.Fprintln(w, string(data))
}
}
}
ResponseWriter
- Write 接收一个字节数组,并写入到HTTP响应主体中
- WriteHeader 改变HTTP响应状态码
- Header 修改HTTP响应首部
package main
import (
json2 "encoding/json"
"fmt"
"net/http"
)
type Post struct {
User string
Threads []string
}
func writeExample(w http.ResponseWriter, r *http.Request) {
str := `<html>
<head><title>Go</title></head>
<body><h1>Hello world</h1></body>
</html>`
w.Write([]byte(str))
}
func writeHeaderExample(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(501)
fmt.Fprintln(w, "No such service, try next door")
}
func headerExample(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Location", "http://baidu.com")
w.WriteHeader(302)
}
func jsonExample(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
post := &Post{
User: "authetic",
Threads: []string{"first", "second"},
}
json, _ := json2.Marshal(post)
w.Write(json)
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/write", writeExample)
http.HandleFunc("/writeheader", writeHeaderExample)
http.HandleFunc("/redirect", headerExample)
http.HandleFunc("/json", jsonExample)
server.ListenAndServe()
}
cookie
Go与cookie
没有设置Expires字段的通常被成为会话cookie,浏览器关闭或刷新cookie就会消失,设置了Expires字段的通常被称为持久cookie,在过期时间之前会一直存在。
func set_cookie(w http.ResponseWriter, r *http.Request) {
c1 := http.Cookie{
Name: "first_cookie",
Value: "Go Web",
HttpOnly: true,
}
c2 := http.Cookie{
Name: "second_cookie",
Value: "Go Web",
HttpOnly: true,
}
http.SetCookie(w, &c1)
http.SetCookie(w, &c2)
}
func get_cookie(w http.ResponseWriter, r *http.Request) {
// h := r.Header["Cookie"]
cl, err := r.Cookie("first_cookie")
if err != nil {
fmt.Fprintln(w, "Something wrong")
}
cs := r.Cookies()
fmt.Fprintln(w, cl)
fmt.Fprintln(w, cs)
}
cookie实现闪现消息
func setMessage(w http.ResponseWriter, r *http.Request) {
msg := []byte("Hello Go")
c := http.Cookie{
Name: "flash",
Value: base64.URLEncoding.EncodeToString(msg),
}
http.SetCookie(w, &c)
}
func showMessage(w http.ResponseWriter, r *http.Request) {
c, err := r.Cookie("flash")
if err != nil {
if err == http.ErrNoCookie {
fmt.Fprintln(w, "No message found")
}
} else {
rc := http.Cookie{
Name: "flash",
MaxAge: -1,
Expires: time.Unix(1, 0),
}
http.SetCookie(w, &rc)
val, _ := base64.URLEncoding.DecodeString(c.Value)
fmt.Fprintln(w, string(val))
}
}
Go Web编程 第四章--处理请求的更多相关文章
- Go Web编程 第三章--接收请求
net/http标准库 net/http标准库通常包括两个部分,客户端和服务器,我们可以通过ListenAndServe创建一个简陋的服务器 package main import ( "n ...
- [转]Windows Shell 编程 第四章 【来源 http://blog.csdn.net/wangqiulin123456/article/details/7987933】
第四章 文件的本质 以前,所有文件和目录都有一个确定的属性集:时间,日期,尺寸,以及表示‘只读的’,‘隐藏的,‘存档的’,或‘系统的’状态标志.然而,Windos95(及后来的WindowsNT4.0 ...
- 读高性能JavaScript编程 第四章 Duff's Device
又要开始罗里吧嗦的 第四章 Summary 了. 这一次我尽量精简语言. 如果你认为 重复调用一个方法数次有点辣眼睛的话 比如: function test(i){ process(i++); pr ...
- Windows核心编程 第四章 进程(下)
4.3 终止进程的运行 若要终止进程的运行,可以使用下面四种方法: • 主线程的进入点函数返回(最好使用这个方法) . • 进程中的一个线程调用E x i t P r o c e s s函数(应该避免 ...
- Windows核心编程 第四章 进程(上)
第4章 进 程 本章介绍系统如何管理所有正在运行的应用程序.首先讲述什么是进程,以及系统如何创建进程内核对象,以便管理每个进程.然后将说明如何使用相关的内核对象来对进程进行操作.接着,要介绍进 ...
- 【读书笔记】C#高级编程 第四章 继承
(一)继承的类型 1.实现继承和接口继承 在面向对象的编程中,有两种截然不同的继承类型:实现继承和接口继承. 实现继承:表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数.在实现继承中, ...
- windows核心编程---第四章 进程
上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了.首先要给大家介绍的是进程内核对象.进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象就是与进程相关联的一个数据结构.操作系统内核通过 ...
- java面向对象编程——第四章 类和对象
OO:面向对象 OOP:面向对象编程 OOA:面向对象分析 OOD:面向对象设计 结构化编程:从顶向下,将一个大问题分解成更小的任务,然后为每一个更小的任务编写一个过程.最后程序员会编写一个主过程来启 ...
- 读高性能JavaScript编程 第四章 Conditionals
if else 和 switch && 递归 if else 和 switch 一般来说,if-else 适用于判断两个离散的值或者判断几个不同的值域.如果判断多于两个离散 ...
随机推荐
- 【多视图几何】TUM 课程 第1章 数学基础:线性代数
在 YouTube 上找到了慕尼黑工业大学(Technische Universitaet München)计算机视觉组 Daniel Cremers 教授的 Multiple View Geomet ...
- MongoDB以Windows Service运行
以Administrator身份打开CMD并输入以下命令 cd D:\Developer\MongoDB\mongodb-win32-x86_64-2.4.6\binD:mongod --logpat ...
- 【codeforces】【比赛题解】#937 CF Round #467 (Div. 2)
没有参加,但是之后几天打了哦,第三场AK的CF比赛. CF大扫荡计划正在稳步进行. [A]Olympiad 题意: 给\(n\)个人颁奖,要满足: 至少有一个人拿奖. 如果得分为\(x\)的有奖,那么 ...
- 如何和统计学家分享数据How to share data with a statistician
如何和统计学家分享数据 原文地址:https://github.com/jtleek/datasharing 将原文渣翻译的版本. 这是一份指南给需要分享数据给统计学家或者数据科学家的任何人.我认为的 ...
- CAS和AQS
一.CAS CAS(Compare And Swap),即比较并交换.是解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数——内存位置(V).预期原值(A)和新值(B).如果内 ...
- idea添加jdbc包
IDEA版本:IDEA 14 这里我使用的第三方jar包是数据库的JDBC jar包导出案例. 1.创建一个Module,名称为dataBase,在里面我们先创建一个folder用来包含所需要的jar ...
- irport报表,把数字金额转换成大写人民币金额
1.编写oracle函数 CREATE OR REPLACE Function MoneyToChinese(Money In Number) Return Varchar2 Is strYuan ) ...
- CSS — 贝塞尔曲线(cubic-bezier)
cubic-bezier 又称三次贝塞尔,主要是为 animation 生成速度曲线的函数,规定是 cubic-bezier(<x1>, <y1>, <x2>, & ...
- C++两个类相互包含引用的问题
在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { B b; } class B { A* a; } 请 ...
- SQL SERVER 断开所有连接(转)
通过sql server management studio对数据进行管理,比如数据库改名等,经常遇到有正在运行的连接,以致无法操作,这时候断掉所有的连接很有必要.代码如下:(会断掉某个库的所有连接, ...