简体   繁体   English

http.HandleFunc每个请求调用根处理程序3次

[英]http.HandleFunc invokes root handler 3 times per request

package main

import (
    "fmt"
    "io"
    "html/template"
    "net/http"
    "log"
)

type pageFunc func() (string, interface{})

func thread() (string, interface{}) {
    return "thread", nil
}

func main() {

    t := template.New("main")
    t.ParseGlob("templates/*.xhtml")

    respond := func(f pageFunc) http.HandlerFunc {
        fmt.Println("respond 1")

        return func(w http.ResponseWriter, r *http.Request) {
            fmt.Println("respond 2")
            name, data := f()
            t.ExecuteTemplate(w, name, data)
        }
    }

    http.HandleFunc("/", respond(thread))
    err := http.ListenAndServe(":7842", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

Starting the program above and sending a single request to http://localhost:7842/ causes the console to output: 启动上述程序并将单个请求发送到http://localhost:7842/导致控制台输出:

respond 1
respond 2
respond 2
respond 2

It only appears to invoke the handler a single time if I comment out: 如果我注释掉,它似乎只调用一次处理程序:

name, data := f()
t.ExecuteTemplate(w, name, data)

In that case I just get: 在这种情况下,我得到:

respond 1
respond 2

This is completely beyond my comprehension. 这完全超出了我的理解。 How would calling t.ExecuteTemplate cause the function it's invoked from to run more than once? 调用t.ExecuteTemplate会如何导致被调用的函数多次运行? Even more bizarre (to me, at least) is that if I change the path slightly, like so, 更奇怪的是(至少对我而言),如果我像这样稍微改变路径,

http.HandleFunc("/a", respond(thread))

... it once again only fires the handler function once, even with the templating function uncommented. ……即使模板函数未注释,它也仅触发处理程序函数一次。 What is happening? 怎么了?

The template in question, if it interests anyone: 有问题的模板,如果有人感兴趣:

{{ define "thread" }}<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>test thread page</title>
        <link rel="stylesheet" type="text/css" href="/static/board.css" />
        <script type="text/javascript" src="/static/general.js"></script>
    </head>

    <body>
        <h1>hello, world.</h1>
    </body>
</html>
{{ end }}

If the "single request" is made by a browser then it may actually be more than one request. 如果“单个请求”是由浏览器发出的,则实际上可能是多个请求。 Eg. 例如。 some browsers may ask for a site favicon. 一些浏览器可能会要求提供网站图标。 If you want a guaranteed single request then I would recommend to write a simple tool for that purpose. 如果您想要一个有保证的单一请求,那么我建议为此目的编写一个简单的工具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM