请求和响应

Request结构

  • URL字段
  • Header字段
  • Body字段
  • Form, PostForm, MultipartForm字段

在处理器函数中,我们可以通过Request获取各个字段的详细信息

  1. func get_request_value(w *http.ResponseWriter, r *http.Request) {
  2. h := r.Header
  3. brower := r.Header.Get("User-Agent")
  4. fme.Fprintln(w, h)
  5. body := make([]byte, r.ContentLength)
  6. r.Body.Read(body)
  7. fmt.Fprintln(w, string(body))
  8. }

Go与HTML表单

用户在表单中输入的数据会以键值对的形式记录在请求的主体中,其中表单中的enctype属性决定了以何种形式发送键值对。默认属性值为application/x-www-form-urlencoded,这个属性会把表单中的数据编码一个连续的长查询字符串,另一种编码方式为multipart/form-data,表单中的数据会被转换为一条MIME报文,每个键值对都构成了这个报文的一部分。简单来说,当表单只需要传送简单数据时,默认编码更加简单,高效;而当表单需要传输大量数据(如文件)时,使用后一种编码方式会更好。有些时候,用户可以通过Base64编码,以文本方式传送二进制数据。

使用Request结构获取表单数据的一般步骤是:

  1. 调用ParseForm或者ParseMultipartForm方法进行语法分析
  2. 访问Form, PostForm, MultipartForm等字段获取数据
  1. func get_form_data1(w http.ResponseWriter, r *http.Request) {
  2. r.ParseForm()
  3. fmt.Fprintln(w, r.Form)
  4. // PostForm字段只支持默认编码,并且只返回表单值,不返回URL查询值
  5. fmt.Fprintln(w, r.PostForm)
  6. }

当使用multipart/form-data编码时,表单数据会被存储到MultipartForm字段中

  1. func get_form_data2(w http.ResponseWriter, r *http.Request) {
  2. r.ParseMultipartForm(1024)
  3. fmt.Fprintln(w, r.MultipartForm)
  4. }

我们也可以使用FormValue或者PostFormValue快速获取表单值,也两个方法会自动调用ParseForm或者ParseMultipartForm方法,其中PostFormValue只会返回表单键值对而不会返回URL键值对

使用FormFile方法可以快速的获取被上传的文件

  1. func process(w http.ResponseWriter, r *http.Request) {
  2. file, _, err := r.FormFile("upload")
  3. if err == nil {
  4. data, err := ioutil.ReadAll(file)
  5. if err == nil {
  6. fmt.Fprintln(w, string(data))
  7. }
  8. }
  9. }

ResponseWriter

  • Write 接收一个字节数组,并写入到HTTP响应主体中
  • WriteHeader 改变HTTP响应状态码
  • Header 修改HTTP响应首部
  1. package main
  2. import (
  3. json2 "encoding/json"
  4. "fmt"
  5. "net/http"
  6. )
  7. type Post struct {
  8. User string
  9. Threads []string
  10. }
  11. func writeExample(w http.ResponseWriter, r *http.Request) {
  12. str := `<html>
  13. <head><title>Go</title></head>
  14. <body><h1>Hello world</h1></body>
  15. </html>`
  16. w.Write([]byte(str))
  17. }
  18. func writeHeaderExample(w http.ResponseWriter, r *http.Request) {
  19. w.WriteHeader(501)
  20. fmt.Fprintln(w, "No such service, try next door")
  21. }
  22. func headerExample(w http.ResponseWriter, r *http.Request) {
  23. w.Header().Set("Location", "http://baidu.com")
  24. w.WriteHeader(302)
  25. }
  26. func jsonExample(w http.ResponseWriter, r *http.Request) {
  27. w.Header().Set("Content-Type", "application/json")
  28. post := &Post{
  29. User: "authetic",
  30. Threads: []string{"first", "second"},
  31. }
  32. json, _ := json2.Marshal(post)
  33. w.Write(json)
  34. }
  35. func main() {
  36. server := http.Server{
  37. Addr: "127.0.0.1:8080",
  38. }
  39. http.HandleFunc("/write", writeExample)
  40. http.HandleFunc("/writeheader", writeHeaderExample)
  41. http.HandleFunc("/redirect", headerExample)
  42. http.HandleFunc("/json", jsonExample)
  43. server.ListenAndServe()
  44. }

cookie

Go与cookie

没有设置Expires字段的通常被成为会话cookie,浏览器关闭或刷新cookie就会消失,设置了Expires字段的通常被称为持久cookie,在过期时间之前会一直存在。

  1. func set_cookie(w http.ResponseWriter, r *http.Request) {
  2. c1 := http.Cookie{
  3. Name: "first_cookie",
  4. Value: "Go Web",
  5. HttpOnly: true,
  6. }
  7. c2 := http.Cookie{
  8. Name: "second_cookie",
  9. Value: "Go Web",
  10. HttpOnly: true,
  11. }
  12. http.SetCookie(w, &c1)
  13. http.SetCookie(w, &c2)
  14. }
  15. func get_cookie(w http.ResponseWriter, r *http.Request) {
  16. // h := r.Header["Cookie"]
  17. cl, err := r.Cookie("first_cookie")
  18. if err != nil {
  19. fmt.Fprintln(w, "Something wrong")
  20. }
  21. cs := r.Cookies()
  22. fmt.Fprintln(w, cl)
  23. fmt.Fprintln(w, cs)
  24. }

cookie实现闪现消息

  1. func setMessage(w http.ResponseWriter, r *http.Request) {
  2. msg := []byte("Hello Go")
  3. c := http.Cookie{
  4. Name: "flash",
  5. Value: base64.URLEncoding.EncodeToString(msg),
  6. }
  7. http.SetCookie(w, &c)
  8. }
  9. func showMessage(w http.ResponseWriter, r *http.Request) {
  10. c, err := r.Cookie("flash")
  11. if err != nil {
  12. if err == http.ErrNoCookie {
  13. fmt.Fprintln(w, "No message found")
  14. }
  15. } else {
  16. rc := http.Cookie{
  17. Name: "flash",
  18. MaxAge: -1,
  19. Expires: time.Unix(1, 0),
  20. }
  21. http.SetCookie(w, &rc)
  22. val, _ := base64.URLEncoding.DecodeString(c.Value)
  23. fmt.Fprintln(w, string(val))
  24. }
  25. }

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. 【多视图几何】TUM 课程 第1章 数学基础:线性代数

    在 YouTube 上找到了慕尼黑工业大学(Technische Universitaet München)计算机视觉组 Daniel Cremers 教授的 Multiple View Geomet ...

  2. MongoDB以Windows Service运行

    以Administrator身份打开CMD并输入以下命令 cd D:\Developer\MongoDB\mongodb-win32-x86_64-2.4.6\binD:mongod --logpat ...

  3. 【codeforces】【比赛题解】#937 CF Round #467 (Div. 2)

    没有参加,但是之后几天打了哦,第三场AK的CF比赛. CF大扫荡计划正在稳步进行. [A]Olympiad 题意: 给\(n\)个人颁奖,要满足: 至少有一个人拿奖. 如果得分为\(x\)的有奖,那么 ...

  4. 如何和统计学家分享数据How to share data with a statistician

    如何和统计学家分享数据 原文地址:https://github.com/jtleek/datasharing 将原文渣翻译的版本. 这是一份指南给需要分享数据给统计学家或者数据科学家的任何人.我认为的 ...

  5. CAS和AQS

    一.CAS CAS(Compare And Swap),即比较并交换.是解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数——内存位置(V).预期原值(A)和新值(B).如果内 ...

  6. idea添加jdbc包

    IDEA版本:IDEA 14 这里我使用的第三方jar包是数据库的JDBC jar包导出案例. 1.创建一个Module,名称为dataBase,在里面我们先创建一个folder用来包含所需要的jar ...

  7. irport报表,把数字金额转换成大写人民币金额

    1.编写oracle函数 CREATE OR REPLACE Function MoneyToChinese(Money In Number) Return Varchar2 Is strYuan ) ...

  8. CSS — 贝塞尔曲线(cubic-bezier)

    cubic-bezier 又称三次贝塞尔,主要是为 animation 生成速度曲线的函数,规定是 cubic-bezier(<x1>, <y1>, <x2>, & ...

  9. C++两个类相互包含引用的问题

    在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { B b; } class B { A* a; } 请 ...

  10. SQL SERVER 断开所有连接(转)

    通过sql server management studio对数据进行管理,比如数据库改名等,经常遇到有正在运行的连接,以致无法操作,这时候断掉所有的连接很有必要.代码如下:(会断掉某个库的所有连接, ...