请求和响应

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结构获取表单数据的一般步骤是:

  1. 调用ParseForm或者ParseMultipartForm方法进行语法分析
  2. 访问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编程 第四章--处理请求的更多相关文章

  1. Go Web编程 第三章--接收请求

    net/http标准库 net/http标准库通常包括两个部分,客户端和服务器,我们可以通过ListenAndServe创建一个简陋的服务器 package main import ( "n ...

  2. [转]Windows Shell 编程 第四章 【来源 http://blog.csdn.net/wangqiulin123456/article/details/7987933】

    第四章 文件的本质 以前,所有文件和目录都有一个确定的属性集:时间,日期,尺寸,以及表示‘只读的’,‘隐藏的,‘存档的’,或‘系统的’状态标志.然而,Windos95(及后来的WindowsNT4.0 ...

  3. 读高性能JavaScript编程 第四章 Duff's Device

    又要开始罗里吧嗦的 第四章  Summary 了. 这一次我尽量精简语言. 如果你认为 重复调用一个方法数次有点辣眼睛的话 比如: function test(i){ process(i++); pr ...

  4. Windows核心编程 第四章 进程(下)

    4.3 终止进程的运行 若要终止进程的运行,可以使用下面四种方法: • 主线程的进入点函数返回(最好使用这个方法) . • 进程中的一个线程调用E x i t P r o c e s s函数(应该避免 ...

  5. Windows核心编程 第四章 进程(上)

    第4章 进 程     本章介绍系统如何管理所有正在运行的应用程序.首先讲述什么是进程,以及系统如何创建进程内核对象,以便管理每个进程.然后将说明如何使用相关的内核对象来对进程进行操作.接着,要介绍进 ...

  6. 【读书笔记】C#高级编程 第四章 继承

    (一)继承的类型 1.实现继承和接口继承 在面向对象的编程中,有两种截然不同的继承类型:实现继承和接口继承. 实现继承:表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数.在实现继承中, ...

  7. windows核心编程---第四章 进程

    上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了.首先要给大家介绍的是进程内核对象.进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象就是与进程相关联的一个数据结构.操作系统内核通过 ...

  8. java面向对象编程——第四章 类和对象

    OO:面向对象 OOP:面向对象编程 OOA:面向对象分析 OOD:面向对象设计 结构化编程:从顶向下,将一个大问题分解成更小的任务,然后为每一个更小的任务编写一个过程.最后程序员会编写一个主过程来启 ...

  9. 读高性能JavaScript编程 第四章 Conditionals

    if else 和 switch    &&    递归 if else 和 switch 一般来说,if-else 适用于判断两个离散的值或者判断几个不同的值域.如果判断多于两个离散 ...

随机推荐

  1. KDE下安装fcitx后终端不能输入中文

    编辑用户的  ~/.profile 文件(或/etc/profile): #fcitx export XIM_PROGRAM=fcitx export XIM=fcitx export GTK_IM_ ...

  2. jenkins 入门教程(上)【转】

    转自:https://www.cnblogs.com/yjmyzz/p/jenkins-tutorial-part-1.html jenkins是一个广泛用于持续构建的可视化web工具,持续构建说得更 ...

  3. 使用nginx sticky实现基于cookie的负载均衡【转】

    在多台后台服务器的环境下,我们为了确保一个客户只和一台服务器通信,我们势必使用长连接.使用什么方式来实现这种连接呢,常见的有使用nginx自带的ip_hash来做,我想这绝对不是一个好的办法,如果前端 ...

  4. 【Andorid开发框架学习】之Volley入门

    Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮.Volley特别适合数据量不大但是通信频繁的场景.在listView显示图片这方面,使用volley也是比较好的,不必 ...

  5. vue全面介绍--全家桶、项目实例

    简介 “简单却不失优雅,小巧而不乏大匠”. 2016年最火的前端框架当属Vue.js了,很多使用过vue的程序员这样评价它,“vue.js兼具angular.js和react.js的优点,并剔除了它们 ...

  6. 分享一个自己写的vue多语言插件smart-vue-i18n

    前言 目前有比较成熟的方案(vue-i18n)了解了下,并且实用了一下感觉对于我在使用的项目来说略显臃肿,功能比较多,所以压缩的会比较大,在移动端不太适合所以自己花一天时间撸了一个vue多语言插件,压 ...

  7. Python 安装requests模块

    window下安装: 注:不要使用 easy_install requests 命令 这种方式安装后不能卸载,建议使用pip 方法 1.自动安装 输入cmd命令进入命令行窗口,执行 pip insta ...

  8. LeetCode828. Unique Letter String

    https://leetcode.com/problems/unique-letter-string/description/ A character is unique in string S if ...

  9. R语言学习笔记:sort、rank、order、arrange排序函数

    R语言中排序有几个基本函数:sort().rank().order().arrange() 一.总结 sort()函数是对向量进行从小到大的排序 rank()函数返回的是对向量中每个数值对应的秩 or ...

  10. Effective STL 学习笔记 31:排序算法

    Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...