之前遇到个问题,在一段代码中这样设置WriteHeader,最后在头中取名字时怎么也取不到。
w.WriteHeader (201) w.Header ()。集(“名字”,“我的名字叫smallsoup”)
用golang写http服务器时,可以很方便可通过w.Header。组(k、v)来设置http响应中头的内容。但是需要特别注意的是:某些时候不仅要修改响应的头,还要修改响应的StatusCode。修改响应的StatusCode可以通过:w.WriteHeader(代码)来实现,例如:
w.WriteHeader (404)
如果这两种修改一起做,就必须让w。WriteHeader在所有的w.Header。集之后,因为w。WriteHeader后设置标题是无效的。
而且必须是在w.Write([]字节(“HelloWorld”)之前,否则会报http:多个响应。WriteHeader称因为其实调用w.Write的时候也会调用WriteHeader()方法,然后将w.wroteHeader置为真的,再次调WriteHeader()则会判断wroteHeader,如果是真正的则会报的错,而且本次调用不生效。
可以看以下源码说明WriteHeader必须在写之前调用。
func (w *响应)WriteHeader(代码int) { 如果w.conn.hijacked () { w.conn.server。logf (“http: response.WriteHeader> 因为我,c:=范围{//规范化:首字母大写//- - - - - -之后单子的首字母大写//如:(主机、用户代理if - modified - since)。 如果上,,a & lt;=c,,c & lt;=' z ' {//大写转小写 c -=低 }else if !上,,A & lt;=c,,c & lt;=' Z ' {//小写转大写 c +=低 }//重新给关键数组赋值 [我]=c//设置大小写标志位 上=c==薄跋麓?/}
正确的调用方式:
服务器:myServer.go
主要包 导入( "net/http” ) 函数main () { http。HandleFunc (“/? func (w http。ResponseWriter r * http.Request) { w.Header ()。集(“名字”,“我的名字叫smallsoup”) w.WriteHeader (500) w。写([]字节(“hello world \ n”)) }) http。nil ListenAndServe (“8080”) }
客户端:
myHttp.go:
主要包 导入( “fmt” “io/ioutil” "net/http” ) 函数main () { myHttpGet () } func myHttpGet () { 负责,犯错:=http.Get (http://localhost: 8080) 如果犯错!=nil { fmt。Println (“myHttpGet错误”,犯错) 返回 } 推迟rsp.Body.Close () 身体,犯错:=ioutil.ReadAll (rsp.Body) 如果犯错!=nil { fmt。Println (“myHttpGet错误”,犯错) 返回 } fmt。rsp.StatusCode Println(“响应statuscode”, “\ nhead[名字]=",rsp.Header(“名字”), “\ nbody”字符串(身体)) }
1。运行服务器
去运行myServer.go
2。运行客户端
去运行myHttp.go
输出如下:statuscode是我们设置的500年,名字也取到了值。
在处理http响应的时候,偶然发现,身体读取之后想再次读取的时候,发现读不到任何东西。见下方代码:
反应,呃=ioutil.ReadAll (resp.Body) 如果犯错!=nil { 日志。Println (“ioutil ReadAll失败:“,err.Error ()) 返回 }
之后如果想再次<代码> ioutil.ReadAll (resp.Body)> 代码的时候会发现读到的是空。于是我决定去看一下这个<代码> resp.Body> 代码,发现它是一个<代码> io.ReadCloser 代码>接口,包含了读者和近接口:
{ReadCloser接口类型 读者 更紧密的 }
于是我想到了文件,它也实现了io.Reader接口,所以用读文件试了下:
字符串函数readFile(路径字符串){ fi犯错:=os.Open(路径) 如果犯错!=nil{恐慌(err)} 推迟fi.Close () byte1犯错:=ioutil.ReadAll (fi) fmt.Println (string (byte1)) byte2犯错:=ioutil.ReadAll (fi) fmt.Println (string (byte2)) 返回字符串(fd) }golang设置http响应响应头与填坑记录