zoukankan      html  css  js  c++  java
  • request response

    Request 结构

    组成:

    • URL字段
    • Header字段
    • 空行
    • Body字段
    • Form字段、postform字段,multipartForm字段

    请求Url

    ·结构·

    type URL struct {
    	Scheme     string
    	Opaque     string    // encoded opaque data
    	User       *Userinfo // username and password information
    	Host       string    // host or host:port
    	Path       string
    	RawPath    string // encoded path hint (Go 1.5 and later only; see EscapedPath method)
    	ForceQuery bool   // append a query ('?') even if RawQuery is empty
    	RawQuery   string // encoded query values, without '?'
    	Fragment   string // fragment for references, without '#'
    }
    

    URL格式一般为
    scheme://[userinfo@]host/path[?query][#fragment]

    http://www.example.com/post?id=123&thread_id=456
    
    id=123&thread_id=456 ==》 RawQuery字段被设置
    
    

    request Header

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func headers(w http.ResponseWriter, r *http.Request) {
    	h := r.Header // 所有请求头
    	
    	// 获取某个请求头
    	// h := r.Header.Get("User-Agent")
    
    	fmt.Fprintln(w, h)
    
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    	http.HandleFunc("/headers", headers)
    	server.ListenAndServe()
    }
    

    request Body

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func body(w http.ResponseWriter, r *http.Request) {
    	// 读取Body字节长度
    	len := r.ContentLength
    
    	// 创建一个字节slice,来存放Body
    	body := make([]byte, len)
    	r.Body.Read(body)
    	fmt.Println(w, string(body))
    
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    	http.HandleFunc("/body", body)
    	server.ListenAndServe()
    }
    

    Form

    // GET
    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func process_form(w http.ResponseWriter, r *http.Request) {
    
    	r.ParseForm() // 先对请求继续语法解析,再访问form字段
    	fmt.Fprintln(w, r.Form)
    
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    	http.HandleFunc("/form", process_form)
    	server.ListenAndServe()
    }
    
    /*
    http://127.0.0.1:8080/form?h=ewrtgy&dsafdsaf=1234
    
    map[h:[ewrtgy] dsafdsaf:[1234]]
    */
    
    

    POST form

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func process_form(w http.ResponseWriter, r *http.Request) {
    
    	// r.PostForm() // 先对请求继续语法解析,再访问form字段
    	fmt.Fprintln(w, r.PostFormValue("dasfsdfadsf"))
    
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    	http.HandleFunc("/form", process_form)
    	server.ListenAndServe()
    }
    
    /*
    http://127.0.0.1:8080/form
    
    username:saltapi_user
    password:sanh123
    eauth:pam
    dasfsdfadsf:["wedfs","asdfsdfdsf"]
    
    
    resp:
    ["wedfs","asdfsdfdsf"]
    
    */
    

    POST FILE

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"net/http"
    )
    
    func post_file(w http.ResponseWriter, r *http.Request) {
    
    	r.ParseMultipartForm(1024)
    
    	// 取出文件头
    	fileHeader := r.MultipartForm.File["uploaded"][0]
    	// fmt.Println(fileHeader)
    	// &{client.sql map[Content-Disposition:[form-data; name="uploaded"; filename="client.sql"] Content-Type:[application/octet-stream]] [] C:UsersHOURU~1AppDataLocalTempmultipart-357262171}
    
    	// 通过文件头来打开文件
    	file, err := fileHeader.Open()
    	if err == nil {
    		data, err := ioutil.ReadAll(file)
    		if err == nil {
    			fmt.Fprintln(w, string(data))
    		}
    	}
    
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    	http.HandleFunc("/post_file", post_file)
    	server.ListenAndServe()
    }
    
    
    • 方法2
    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"net/http"
    )
    
    func post_file(w http.ResponseWriter, r *http.Request) {
    	
    	// FormFile 返回的是文件和文件头作为结果, 使用FormFile后不需要手动调用ParseMultipartForm方法
    	file, _, err := r.FormFile("uploaded") 
    	if err == nil {
    		data, err := ioutil.ReadAll(file)
    		if err == nil {
    			fmt.Fprintln(w, string(data))
    		}
    
    	}
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    	http.HandleFunc("/post_file", post_file)
    	server.ListenAndServe()
    }
    
    

    response

    ResponseWriter是一个接口,处理器可通过这个接口创建HTTP response,ResponseWriter会在创建响应时会用到http.response结构

    为何ServerHttp为什么要接收ResponseWriter接口和Request指针作为参数,原因是为了让服务器可以觉察到处理器对Request结构的修改,我们必须引用(pass by reference)而不是传值(pass by value)的方式传递Request结构, 源码中ResponseWriter 、Request都是传引用(指针)而不是值

    ResponseWriter拥有以下接口:

    • Write
    • WriteHeader
    • Header

    Write 接收一个字节数组作为参数,并将数组中的字节写入Http响应的主体中.

    package main
    
    import "net/http"
    
    func writeExample(w http.ResponseWriter, r *http.Request) {
    
    	str := `<html>
    <head><title>Go Web Programming</title></head>
    <body><h1>Hello World</h1></body>
    </html>`
    
    	//  通过Write方法将一段HTML字符串写入Http响应的body中, 没有设置Content-Type类型,
    	// Write会自动检测并设置正确的类型
    	w.Write([]byte(str))
    
    	/*
    	   WriteHeader 并不可以设置响应的头首部;
    	   Header方法才可以;
    	   WriteHeader方法接收一个代表HTTP响应状态码(int 类型)作为参数作为HTTP响应的状态码;
    	   再调用这个方法后,用户可以继续对ResponseWrite进行写入,但是不能对响应头的首部做任何写入操作;
    	   如果用户在调用Write方法之前没有执行过WriteHeader方法,程序会默认使用200 OK 作为响应作为响应的状态码
    
    	*/
    
    	// WriteHeader
    	/*
    		WriteHeader 可以自定义 返回 501 Not Implemented
    	*/
    
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    	http.HandleFunc("/write", writeExample)
    	server.ListenAndServe()
    }
    
    

    自定义返回状态码

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func writeExample(w http.ResponseWriter, r *http.Request) {
    
    	str := `<html>
    <head><title>Go Web Programming</title></head>
    <body><h1>Hello World</h1></body>
    </html>`
    
    	//  通过Write方法将一段HTML字符串写入Http响应的body中, 没有设置Content-Type类型,
    	// Write会自动检测并设置正确的类型
    	w.Write([]byte(str))
    }
    
    func write_Example_HeaderExample(w http.ResponseWriter, r *http.Request) {
    	w.WriteHeader(501)
    	fmt.Fprintln(w, "没有服务,请尝试使用请求其他URL")
    }
    
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    
    	http.HandleFunc("/write", writeExample)
    	http.HandleFunc("/write_header", write_Example_HeaderExample)
    
    	server.ListenAndServe()
    }
    

    302重定向

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    /*func writeExample(w http.ResponseWriter, r *http.Request) {
    
    	str := `<html>
    <head><title>Go Web Programming</title></head>
    <body><h1>Hello World</h1></body>
    </html>`
    
    	w.Write([]byte(str))
    }
    
    func write_Example_HeaderExample(w http.ResponseWriter, r *http.Request) {
    	w.WriteHeader(501)
    	fmt.Fprintln(w, "没有服务,请尝试使用请求其他URL")
    }*/
    
    func redirect_header(w http.ResponseWriter, r *http.Request) {
    	w.Header().Set("Location", "http://httpbin.org/")
    	w.WriteHeader(302)
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    
    	//http.HandleFunc("/write", writeExample)
    	//http.HandleFunc("/write_header", write_Example_HeaderExample)
    	http.HandleFunc("/redirect", redirect_header)
    
    	server.ListenAndServe()
    }
    
    

    json

    package main
    
    import (
    	"encoding/json"
    
    	"net/http"
    )
    
    func redirect_header(w http.ResponseWriter, r *http.Request) {
    	w.Header().Set("Location", "http://httpbin.org/")
    	w.WriteHeader(302)
    }
    
    type Post_info struct {
    	User    string
    	Threads []string
    }
    
    func jsonExample(w http.ResponseWriter, r *http.Request) {
    	w.Header().Set("Content-type", "application/json")
    	post := &Post_info{
    		User:    "张三",
    		Threads: []string{"一", "二"},
    	}
    	json, _ := json.Marshal(post)
    	w.Write(json)
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    
    	http.HandleFunc("/redirect", redirect_header)
    	http.HandleFunc("/json", jsonExample)
    
    	server.ListenAndServe()
    }
    
    

    cookie cookie是存储在客户端、体积较小的信息,信息最初都是由服务器通过HTTP响应报文头设置。每当客户端请求时cookie会随着请求一同发送到服务器; cookie设计本意是克服http是无状态性,虽不是唯一的方法,但是是最常用的方法之一,比如广告用户行为.....

    cookie种类有很多, 大致分为会话cookie和持久cookie两种类型,其他cookie通常是持久cookie的变种.

    cookie在go语言里的使用Cookie结构表示

    type Cookie struct {
    	Name  string
    	Value string
    
    	Path       string    // optional
    	Domain     string    // optional
    	Expires    time.Time // optional
    	RawExpires string    // for reading cookies only
    
    	// MaxAge=0 means no 'Max-Age' attribute specified.
    	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
    	// MaxAge>0 means Max-Age attribute present and given in seconds
    	MaxAge   int
    	Secure   bool
    	HttpOnly bool
    	Raw      string
    	Unparsed []string // Raw text of unparsed attribute-value pairs
    }
    
    /*
    Expires  字段没有设置则被称为临时cookie,浏览器被关闭时自动清除
    
    Expires 明确指明cookie何时过期,
    MaxAge  指明cookie在被浏览器创建出来以后能够存活多少秒
    
    两种不同的机制与浏览器设置有关,与语言无关
    
    */
    
    

    设置cookie

    方法1

    package main
    
    import (
    	"net/http"
    )
    
    func set_cookie(w http.ResponseWriter, r *http.Request) {
    	c1 := http.Cookie{
    		Name:     "youname",
    		Value:    "centos 111 go web",
    		HttpOnly: true,
    	}
    	c2 := http.Cookie{
    		Name:     "what",
    		Value:    "some1 2222",
    		HttpOnly: true,
    	}
    	w.Header().Set("Set-Cookie", c1.String())
    	w.Header().Set("Set-Cookie", c2.String())
    
    }
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    
    	http.HandleFunc("/setcookie", set_cookie)
    
    	server.ListenAndServe()
    }
    
    

    方法2 http.SetCookie

    package main
    
    import (
    	"net/http"
    )
    
    func set_cookie(w http.ResponseWriter, r *http.Request) {
    	c1 := http.Cookie{
    		Name:     "youname",
    		Value:    "centos 111 go web",
    		HttpOnly: true,
    	}
    	c2 := http.Cookie{
    		Name:     "what",
    		Value:    "some1 2222",
    		HttpOnly: true,
    	}
    	w.Header().Set("Set-Cookie", c1.String())
    	w.Header().Set("Set-Cookie", c2.String())
    
    }
    
    func set_cookie1(w http.ResponseWriter, r *http.Request) {
    	c1 := http.Cookie{
    		Name:     "youname",
    		Value:    "centos 111 go web",
    		HttpOnly: true,
    	}
    	c2 := http.Cookie{
    		Name:     "what",
    		Value:    "some1 2222",
    		HttpOnly: true,
    	}
    	http.SetCookie(w, &c1) // SetCookie使用的是指针,而不是cookie本身
    	http.SetCookie(w, &c2)
    }
    
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    
    	http.HandleFunc("/setcookie", set_cookie)
    	http.HandleFunc("/setcookie1", set_cookie1)
    
    	server.ListenAndServe()
    }
    
    
    • 获取cookie
    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func set_cookie1(w http.ResponseWriter, r *http.Request) {
    	c1 := http.Cookie{
    		Name:     "youname",
    		Value:    "centos 111 go web",
    		HttpOnly: true,
    	}
    	c2 := http.Cookie{
    		Name:     "what",
    		Value:    "some1 2222",
    		HttpOnly: true,
    	}
    	http.SetCookie(w, &c1)
    	http.SetCookie(w, &c2)
    }
    
    func get_cooke(w http.ResponseWriter, r *http.Request) {
    	h := r.Header["Cookie"]
    	fmt.Fprintln(w, h)
    }
    
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    
    	http.HandleFunc("/setcookie1", set_cookie1)
    	http.HandleFunc("/get_cooke", get_cooke)
    
    	server.ListenAndServe()
    }
    
    • 方法2
    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func set_cookie1(w http.ResponseWriter, r *http.Request) {
    	c1 := http.Cookie{
    		Name:     "youname",
    		Value:    "centos 111 go web",
    		HttpOnly: true,
    	}
    	c2 := http.Cookie{
    		Name:     "what",
    		Value:    "some1 2222",
    		HttpOnly: true,
    	}
    	http.SetCookie(w, &c1)
    	http.SetCookie(w, &c2)
    }
    
    func get_cooke(w http.ResponseWriter, r *http.Request) {
    	h := r.Header["Cookie"]
    	fmt.Fprintln(w, h)
    }
    
    func get_cooke2(w http.ResponseWriter, r *http.Request) {
    
    	//  request 提供了Cookie方法
    	c1, err := r.Cookie("youname")
    	if err != nil {
    		fmt.Fprintln(w, "Cannot get the first cookie")
    	}
    	cs := r.Cookies()
    
    	fmt.Fprintln(w, c1)
    	fmt.Fprintln(w, cs)
    }
    
    func main() {
    	server := http.Server{Addr: "127.0.0.1:8080"}
    
    	http.HandleFunc("/setcookie1", set_cookie1)
    	http.HandleFunc("/get_cooke", get_cooke)
    
    	http.HandleFunc("/get_cooke2", get_cooke2)
    
    	server.ListenAndServe()
    }
    
    
    • 消息闪现
    package main
    
    import (
    	"encoding/base64"
    	"fmt"
    	"net/http"
    	"time"
    )
    
    func setMessage(w http.ResponseWriter, r *http.Request) {
    	msg := []byte("Hello world! 世界")
    	c := http.Cookie{
    		Name:  "flash_message",
    		Value: base64.URLEncoding.EncodeToString(msg), // base64解析是去除空格特殊字符,符合URL编码要求
    	}
    	http.SetCookie(w, &c)
    }
    func showMessage(w http.ResponseWriter, r *http.Request) {
    	c, err := r.Cookie("flash_message")
    	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), // 设置时间为过去的时间浏览器会自动清除cookie
    		}
    		http.SetCookie(w, &rc)
    		val, _ := base64.URLEncoding.DecodeString(c.Value)
    		fmt.Fprintln(w, string(val))
    	}
    }
    
    func main() {
    	server := http.Server{
    		Addr: "127.0.0.1:8080",
    	}
    	http.HandleFunc("/set_message", setMessage)
    	http.HandleFunc("/show_message", showMessage)
    	server.ListenAndServe()
    
    }
    
  • 相关阅读:
    ZOJ 3705 Applications
    UVA 220 Othello
    HDU 2084 数塔
    第五章:变量
    第四章:注释
    第三章:程序结构
    第二章:项目的创建和环境熟悉
    第一章:c#开发环境安装
    处理字段串
    查询表的列信息
  • 原文地址:https://www.cnblogs.com/zrdpy/p/8615641.html
Copyright © 2011-2022 走看看