HandleFunc被调用两次

huangapple go评论131阅读模式
英文:

HandleFunc being called twice

问题

我正在使用Go语言遵循一个简单的Web服务器示例。

我插入了一个log语句,所以最终的代码如下所示:

  1. package main
  2. import (
  3. "io"
  4. "log"
  5. "net/http"
  6. )
  7. func hello(w http.ResponseWriter, r *http.Request) {
  8. io.WriteString(w, "Hello world!")
  9. log.Println("hello.")
  10. }
  11. func main() {
  12. mux := http.NewServeMux()
  13. mux.HandleFunc("/", hello)
  14. http.ListenAndServe(":8000", mux)
  15. }

问题是,每当我在Web浏览器中加载端口8000时,这个函数会被调用两次。这是一个问题,因为我打算在每次访问页面时递增一个计数器。由于这种行为,计数器会被递增两次。另一方面,如果我使用curl localhost:8000命令,它只会被调用一次。

我觉得我在这里漏掉了一些非常愚蠢的东西。

英文:

I am following a simple web server example in Go.

I inserted a log statement so that the resulting code looks like below:

  1. package main
  2. import (
  3. "io"
  4. "log"
  5. "net/http"
  6. )
  7. func hello(w http.ResponseWriter, r *http.Request) {
  8. io.WriteString(w, "Hello world!")
  9. log.Println("hello.")
  10. }
  11. func main() {
  12. mux := http.NewServeMux()
  13. mux.HandleFunc("/", hello)
  14. http.ListenAndServe(":8000", mux)
  15. }

Problem is that whenever I load port 8000 in my web browser, this function is called twice. This is an issue because I intend to increment a counter on each page visit. With this behavior, counter gets incremented twice. OTOH, if I do curl localhost:8000, it is called only once.

I feel it's something really silly that I am missing here.

答案1

得分: 41

只需记录请求即可。您会发现您的浏览器也会请求 /favicon.ico。

有关更多信息,请参阅 https://en.wikipedia.org/wiki/Favicon

英文:

Just log the requests. You will realize that your browser also requests /favicon.ico.

See https://en.wikipedia.org/wiki/Favicon for more information.

答案2

得分: 21

如果您是从服务中发出请求,那么没问题,但如果您是从浏览器进行测试,并且不是为了生产意图,您可以在Golang代码中执行以下操作以避免浏览器加载favicon:

  1. http.HandleFunc("/favicon.ico", doNothing)
  2. func doNothing(w http.ResponseWriter, r *http.Request){}

对于投票给负面的人:这是有效的,抱歉在不需要favicon或其他内容的API中使用这段代码...

英文:

If you request from a service is fine, but if you test from a browser and is not the production intention you can do this in golang code for avoid browser load the favicon:

  1. http.HandleFunc("/favicon.ico", doNothing)

And the function

  1. func doNothing(w http.ResponseWriter, r *http.Request){}

For people voting negatives: this works, sorry for handle it with this code in an api that doesn't need favicon or whatever...

答案3

得分: 3

根据Didier的说法,这是你的浏览器尝试加载网站图标。你可以通过将以下代码添加到标签中来阻止这种情况发生:

  1. <link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
英文:

As Didier says, it's your browser trying to load the favicon. You can prevent this by adding this code to the &lt;head&gt;:

  1. &lt;link rel=&quot;icon&quot; type=&quot;image/png&quot; href=&quot;data:image/png;base64,iVBORw0KGgo=&quot;&gt;

答案4

得分: 3

根据Didier Spezia所说,"/"是一个子树路径的示例(因为它以斜杠结尾)。另一个示例可能是"/static/"。当请求的URL路径的开头与子树路径匹配时,子树路径模式将被匹配(并调用相应的处理程序)。如果有助于你的理解,你可以将子树路径视为在末尾有一个通配符,类似于"/**""/static/**"。这解释了为什么"/"模式充当了一个捕获所有的作用。该模式实际上意味着匹配一个斜杠,后面跟着任何内容(或根本没有内容)。

为了防止这种情况发生,只需在你的hello处理程序中添加一个检查,如下所示:

  1. func hello(w http.ResponseWriter, r *http.Request) {
  2. if r.URL.Path != "/" {
  3. http.NotFound(w, r)
  4. return
  5. }
  6. io.WriteString(w, "Hello world!")
  7. log.Println("hello.")
  8. }
英文:

Building on what Didier Spezia said,
&quot;/&quot; is an example of a subtree path (because it ends in a trailing
slash). Another example would be something like &quot;/static/&quot;. Subtree path patterns are
matched (and the corresponding handler called) whenever the start of a request URL path
matches the subtree path. If it helps your understanding, you can think of subtree paths as
acting a bit like they have a wildcard at the end, like &quot;/**&quot; or &quot;/static/**&quot; .
This helps explain why the &quot;/&quot; pattern is acting as a catch-all. The pattern essentially
means match a single slash, followed by anything (or nothing at all).

To prevent that from happening,
just add a check in your hello handler like so

  1. func hello(w http.ResponseWriter, r *http.Request) {
  2. if r.URL.Path != &quot;/&quot; {
  3. http.NotFound(w, r)
  4. return
  5. }
  6. io.WriteString(w, &quot;Hello world!&quot;)
  7. log.Println(&quot;hello.&quot;)
  8. }

huangapple
  • 本文由 发表于 2015年10月30日 17:04:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/33432192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定