Golang語言如何讀取http.Request中body的內(nèi)容
Golang讀取http.Request中body內(nèi)容
不羅嗦了,直接貼代碼,不曉得為什么搞這么復(fù)雜,是不是因為擔(dān)心 body 內(nèi)容一次接受不全,所以搞了個接口來讀取其中的內(nèi)容?
import ( ... "io/ioutil" ... ) ... func myPost(w http.ResponseWriter, r *http.Request) { s, _ := ioutil.ReadAll(r.Body) //把 body 內(nèi)容讀入字符串 s fmt.Fprintf(w, "%s", s) //在返回頁面中顯示內(nèi)容。 } ...
Golang http.Request復(fù)用
針對除了Get以外的請求
package main import ( "net/http" "strings" ) func main(){ reader := strings.NewReader("hello") req,_ := http.NewRequest("POST","http://www.abc.com",reader) client := http.Client{} client.Do(req) // 第一次會請求成功 client.Do(req) // 請求失敗 }
第二次請求會出錯
http: ContentLength=5 with Body length 0
原因是第一次請求后req.Body已經(jīng)讀取到結(jié)束位置,所以第二次請求時無法再讀取body,
解決方法:
重新定義一個ReadCloser的實現(xiàn)類替換req.Body
package reader import ( "io" "net/http" "strings" "sync/atomic" ) type Repeat struct{ reader io.ReaderAt offset int64 } // Read 重寫讀方法,使每次讀取request.Body時能從指定位置讀取 func (p *Repeat) Read(val []byte) (n int, err error) { n, err = p.reader.ReadAt(val, p.offset) atomic.AddInt64(&p.offset, int64(n)) return } // Reset 重置偏移量 func (p *Repeat) Reset(){ atomic.StoreInt64(&p.offset,0) } func (p *Repeat) Close() error { // 因為req.Body實現(xiàn)了readcloser接口,所以要實現(xiàn)close方法 // 但是repeat中的值有可能是只讀的,所以這里只是嘗試關(guān)閉一下。 if p.reader != nil { if rc, ok := p.reader.(io.Closer); ok { return rc.Close() } } return nil } func doPost() { client := http.Client{} reader := strings.NewReader("hello") req , _ := http.NewRequest("POST","http://www.abc.com",reader) req.Body = &Repeat{reader:reader,offset:0} client.Do(req) // 將偏移量重置為0 req.Body.(*Repeat).Reset() client.Do(req) }
這樣就不會報錯了,因為也重寫了Close()方法,所以同時也解決了request重用時,req.Body自動關(guān)閉的問題。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Go初學(xué)者踩坑之go?mod?init與自定義包的使用
go?mod是go的一個模塊管理工具,用來代替?zhèn)鹘y(tǒng)的GOPATH方案,下面這篇文章主要給大家介紹了關(guān)于Go初學(xué)者踩坑之go?mod?init與自定義包的使用,需要的朋友可以參考下2022-10-10