go编程中,无法打印POST FormValue。

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

go programming POST FormValue can't be printed

问题

在我开始之前,我要先解释一下背景情况,我对Go编程语言非常陌生。我在Win 7上运行Go,使用的是最新的Windows安装包。我对编码不太擅长,但我喜欢学习一门新语言的挑战。我本想开始学习Erlang,但在YouTube上看了一些关于Go I/O的视频后,发现Go非常有趣。

我在Go中遇到了一个问题,无法捕获POST表单的值。昨天我花了三个小时尝试让Go在浏览器中打印POST表单的值,但失败了。我不知道我做错了什么,有人能指点我正确的方向吗?在其他语言(如C#,PHP,VB,ASP,Rails等)中,我可以很容易地做到这一点。我已经搜索了整个互联网,但没有找到可用的示例。以下是我的示例代码。

这是Index.html页面

{{ define "title" }}Homepage{{ end }}

{{ define "content" }}
    <h1>My Homepage</h1>

    <p>Hello, and welcome to my homepage!</p>
	<form method="POST" action="/">
	<p> Enter your name : <input type="text" name="username"> </P>
	<p> <button>Go</button>
	</form>
	<br /><br />

{{ end }}

这是基本页面

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>{{ template "title" . }}</title>
    </head>
    <body>
        <section id="contents">
            {{ template "content" . }}
        </section>
        <footer id="footer">
            My homepage 2012 copy
        </footer>
    </body>
</html>

现在是一些Go代码

package main

import (
	"fmt"
	"http"
	"strings"
	"html/template"

)

var index = template.Must(template.ParseFiles(
  "templates/_base.html",
  "templates/index.html",
))


func GeneralHandler(w http.ResponseWriter, r *http.Request) {
	index.Execute(w, nil)
	 if r.Method == "POST" {
		a := r.FormValue("username")
		fmt.Fprintf(w, "hi %s!",a); //<-- 这个变量在浏览器中没有显示!!!

	}
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
    remPartOfURL := r.URL.Path[len("/hello/"):] 
    fmt.Fprintf(w, "Hello %s!", remPartOfURL)
}


func main() {
	http.HandleFunc("/", GeneralHandler)
    http.HandleFunc("/hello/", helloHandler)
    http.ListenAndServe("localhost:81", nil)
}

谢谢!

PS:在stackoverflow上的每一行代码前都要添加四个空格非常繁琐,特别是当你在复制粘贴时。我觉得这不太用户友好,是否有更简单的方法?

英文:

Before I being a bit of background, I am very new to go programming language. I am running go on Win 7, latest go package installer for windows. I'm not good at coding but I do like some challenge of learning a new language. I wanted to start learn Erlang but found go very interesting based on the GO I/O videos in youtube.

I'm having problem with capturing POST form values in GO. I spend three hours yesterday to get go to print a POST form value in the browser and failed miserably. I don't know what I'm doing wrong, can anyone point me to the right direction? I can easily do this in another language like C#, PHP, VB, ASP, Rails etc. I have search the entire interweb and haven't found a working sample. Below is my sample code.

Here is Index.html page

{{ define &quot;title&quot; }}Homepage{{ end }}

{{ define &quot;content&quot; }}
    &lt;h1&gt;My Homepage&lt;/h1&gt;

    &lt;p&gt;Hello, and welcome to my homepage!&lt;/p&gt;
	&lt;form method=&quot;POST&quot; action=&quot;/&quot;&gt;
	&lt;p&gt; Enter your name : &lt;input type=&quot;text&quot; name=&quot;username&quot;&gt; &lt;/P&gt;
	&lt;p&gt; &lt;button&gt;Go&lt;/button&gt;
	&lt;/form&gt;
	&lt;br /&gt;&lt;br /&gt;

{{ end }}

Here is the base page

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;title&gt;{{ template &quot;title&quot; . }}&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;section id=&quot;contents&quot;&gt;
            {{ template &quot;content&quot; . }}
        &lt;/section&gt;
        &lt;footer id=&quot;footer&quot;&gt;
            My homepage 2012 copy
        &lt;/footer&gt;
    &lt;/body&gt;
&lt;/html&gt;

now some go code

    package main

import (
	&quot;fmt&quot;
	&quot;http&quot;
	&quot;strings&quot;
	&quot;html/template&quot;

)

var index = template.Must(template.ParseFiles(
  &quot;templates/_base.html&quot;,
  &quot;templates/index.html&quot;,
))


func GeneralHandler(w http.ResponseWriter, r *http.Request) {
	index.Execute(w, nil)
	 if r.Method == &quot;POST&quot; {
		a := r.FormValue(&quot;username&quot;)
		fmt.Fprintf(w, &quot;hi %s!&quot;,a); //&lt;-- this variable does not rendered in the browser!!!

	}
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
    remPartOfURL := r.URL.Path[len(&quot;/hello/&quot;):] 
    fmt.Fprintf(w, &quot;Hello %s!&quot;, remPartOfURL)
}


func main() {
	http.HandleFunc(&quot;/&quot;, GeneralHandler)
    http.HandleFunc(&quot;/hello/&quot;, helloHandler)
    http.ListenAndServe(&quot;localhost:81&quot;, nil)
}

Thanks!

PS: Very tedious to add four space before every line of code in stackoverflow especially when you are copy pasting. Didn't find it very user friendly or is there an easier way?

答案1

得分: 3

在从请求中读取值之前,通过调用Execute向ResponseWriter写入内容会清除它。

如果您使用以下请求处理程序,您可以看到这一点:

func GeneralHandler(w http.ResponseWriter, r *http.Request) {
   fmt.Println(r.Method)
   fmt.Println(r.URL)
   fmt.Println("before", r.FormValue("username"))
   index.Execute(w, nil)
   if r.Method == "POST" {
     fmt.Println("after", r.FormValue("username"))
   } 
}

这将打印出"before"和"after"。然而,在这种情况下:

func GeneralHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Println(r.Method)
  fmt.Println(r.URL)
  index.Execute(w, nil)
  if r.Method == "POST" {
    fmt.Println("after", r.FormValue("username"))
  }
}

"after"的值将为空。

英文:

Writing to the ResponseWriter (by calling Execute) before reading the value from the request is clearing it out.

You can see this in action if you use this request handler:

func GeneralHandler(w http.ResponseWriter, r *http.Request) {
   fmt.Println(r.Method)
   fmt.Println(r.URL)
   fmt.Println(&quot;before&quot;,r.FormValue(&quot;username&quot;))
   index.Execute(w, nil)
   if r.Method == &quot;POST&quot; {
     fmt.Println(&quot;after&quot;,r.FormValue(&quot;username&quot;))
   } 
 }

This will print out before and after. However, in this case:

func GeneralHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Println(r.Method)
  fmt.Println(r.URL)
  index.Execute(w, nil)
  if r.Method == &quot;POST&quot; {
    fmt.Println(&quot;after&quot;,r.FormValue(&quot;username&quot;))
  }
}

The after value will be blank.

答案2

得分: 1

根据html/template的文档,Execute的第二个参数应该是您想要放入模板中的数据。

在模板中的某个地方添加{{.}},然后将要打印的字符串作为第二个参数传递。它应该作为模板的一部分被渲染出来。

英文:

According to the documentation for html/template the second argument to Execute should be the data you want to put in the template.

Add a {{.}} somewhere in your template and then pass the string you want printed in as the second argument. It should get rendered as part of the template.

huangapple
  • 本文由 发表于 2012年9月27日 08:31:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/12612409.html
匿名

发表评论

匿名网友

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

确定