我有最基本的net/http程序,我用来学习Go中的命名空间:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL)
go HandleIndex(w, r)
})
fmt.Println("Starting Server...")
log.Fatal(http.ListenAndServe(":5678", nil))
}
func HandleIndex(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("Hello, World!"))
}
Run Code Online (Sandbox Code Playgroud)
当我运行程序并连接到localhost:5678Chrome时,我在控制台中得到了这个:
Starting Server...
/
2015/01/15 13:41:29 http: multiple response.WriteHeader calls
/favicon.ico
2015/01/15 13:41:29 http: multiple response.WriteHeader calls
Run Code Online (Sandbox Code Playgroud)
但我不明白这是怎么可能的.我打印URL,启动一个新的goroutine,写一次标题,并给它一个静态的身体Hello, World!似乎正在发生两件事之一.幕后的任何东西都在写另一个标题,或者以某种方式HandleIndex为同一个请求调用两次.我该怎么做才能停止写多个标题?
编辑:它似乎与该go HandleIndex(w, r)行有关,因为如果我删除go并只是使它成为函数调用而不是goroutine,我没有任何问题,浏览器获取它的数据.由于它是goroutine,我得到多个WriteHeader错误,浏览器不显示"Hello World".为什么要把这个打破呢?
icz*_*cza 53
看一下您注册为传入请求处理程序的匿名函数:
func(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL)
go HandleIndex(w, r)
}
Run Code Online (Sandbox Code Playgroud)
它打印URL(到标准输出),然后调用HandleIndex()新的goroutine并继续执行.
如果您有一个处理程序函数,在第一次调用之前没有设置响应状态Write,Go将自动将响应状态设置为200(HTTP OK).如果处理程序函数没有向响应写入任何内容(并且没有设置响应状态并正常完成),那么这也被视为对请求的成功处理,并且将发回响应状态200.你的匿名函数没有设置它,它甚至没有写任何响应.所以Go会这样做:将响应状态设置为200 HTTP OK.
请注意,处理每个请求都在其自己的goroutine中运行.
因此,如果你调用HandleIndex一个新的goroutine,你的原始匿名函数将继续:它将结束,因此响应头将被设置 - 同时(同时)你的启动新goroutine也将设置响应头 - 因此"multiple response.WriteHeader calls"错误.
如果你删除了"go",你的HandleIndex函数会在你的处理函数返回之前在同一个goroutine中设置响应头,并且"net/http"会知道这个并且不会再尝试设置响应头,所以你遇到的错误将会不会发生.
| 归档时间: |
|
| 查看次数: |
36275 次 |
| 最近记录: |