获取Go语言表单的数据未收到

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

Getting No data received for go language form

问题

这是astaxie的书中的简单表单。当我尝试访问'/login'时,我得到以下错误信息:

没有接收到数据 { 无法加载网页,因为服务器未发送任何数据。错误代码:ERR_EMPTY_RESPONSE }

以下是代码:

main.go

package main
import (
    "fmt"
    "html/template"
    "net/http"

)

func sayhelloName(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello astaxie!") // 将数据写入响应
}

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method) // 获取请求方法
    if r.Method == "GET" {
      t, err :=template.New("").Parse(loginHtml)
      if err != nil {
          panic(err)
      }

      const loginHtml = `
      <html>
      <head>
      <title></title>
      </head>
      <body>
      <form action="/login" method="post">
          Username:<input type="text" name="username">
          Password:<input type="password" name="password">
          <input type="submit" value="Login">
      </form>
      </body>
      </html>
      `

    }    else {
        r.ParseForm()
        // 登录逻辑部分
        fmt.Println("username:", r.PostFormValue("username"))
        fmt.Println("password:", r.PostFormValue("password"))
    }
}


func main() {
    http.HandleFunc("/", sayhelloName) // 设置路由规则
    http.HandleFunc("/login", login)
   http.ListenAndServe(":9090", nil) // 设置监听端口

}

#login.gtpl
<html>
<head>
<title></title>
</head>
<body>
<form action="/login" method="post">
    Username:<input type="text" name="username">
    Password:<input type="password" name="password">
    <input type="submit" value="Login">
</form>
</body>
</html>

有什么问题吗

<details>
<summary>英文:</summary>

 It&#39;s the simple form from astaxie&#39;s book 
 when I try &#39;/login&#39; , I get

 

    No Data received { Unable to load the webpage because the server sent no data.   Error code: ERR_EMPTY_RESPONSE }

    
Here&#39;s the code:

   **main.go**

    package main
    import (
        &quot;fmt&quot;
        &quot;html/template&quot;
        &quot;net/http&quot;
    
    )
    
    func sayhelloName(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, &quot;Hello astaxie!&quot;) // write data to response
    }
    
    func login(w http.ResponseWriter, r *http.Request) {
        fmt.Println(&quot;method:&quot;, r.Method) //get request method
        if r.Method == &quot;GET&quot; {
          t, err :=template.New(&quot;&quot;).Parse(loginHtml)
          if err != nil {
              panic(err)
          }
    
          const loginHtml = `
          &lt;html&gt;
          &lt;head&gt;
          &lt;title&gt;&lt;/title&gt;
          &lt;/head&gt;
          &lt;body&gt;
          &lt;form action=&quot;/login&quot; method=&quot;post&quot;&gt;
              Username:&lt;input type=&quot;text&quot; name=&quot;username&quot;&gt;
              Password:&lt;input type=&quot;password&quot; name=&quot;password&quot;&gt;
              &lt;input type=&quot;submit&quot; value=&quot;Login&quot;&gt;
          &lt;/form&gt;
          &lt;/body&gt;
          &lt;/html&gt;
          `
    
        }    else {
            r.ParseForm()
            // logic part of log in
            fmt.Println(&quot;username:&quot;, r.PostFormValue(&quot;username&quot;))
            fmt.Println(&quot;password:&quot;, r.PostFormValue(&quot;password&quot;))
        }
    }
    
    
    func main() {
        http.HandleFunc(&quot;/&quot;, sayhelloName) // setting router rule
        http.HandleFunc(&quot;/login&quot;, login)
       http.ListenAndServe(&quot;:9090&quot;, nil) // setting listening port
    
    }
    
    #login.gtpl
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;form action=&quot;/login&quot; method=&quot;post&quot;&gt;
        Username:&lt;input type=&quot;text&quot; name=&quot;username&quot;&gt;
        Password:&lt;input type=&quot;password&quot; name=&quot;password&quot;&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Login&quot;&gt;
    &lt;/form&gt;
    &lt;/body&gt;
    &lt;/html&gt;
    
    Any idea??


</details>


# 答案1
**得分**: 2

你原始问题的问题已经编辑了几次是你的`ParseFiles()`函数失败了它无法读取你的模板文件你之前不知道这个问题因为你忽略了它返回的`error`_千万不要这样做_你至少可以打印出错误或者在出现错误时调用`panic(err)`如果你这样做了你就能立即看到问题的原因

如果你指定了相对路径`login.gtpl`文件必须放在你启动应用程序的工作目录中或者指定一个绝对路径

在解决问题之前你也可以将你的HTML源代码放入Go文件中像这样

```go
t, err := template.New("").Parse(loginHtml)
if err != nil {
    panic(err)
}
t.Execute(w, nil)
// ... the rest of your code

在你的.go源文件的末尾(login()函数之外)插入以下内容:

const loginHtml = `
<html>
<head>
<title></title>
</head>
<body>
<form action="/login" method="post">
    Username:<input type="text" name="username">
    Password:<input type="password" name="password">
    <input type="submit" value="Login">
</form>
</body>
</html>

注意1:

由于你的HTML模板只是一个静态HTML,在当前形式下,你可以直接将其发送到输出,而无需构建和执行模板:

// Instead of calling template.New(...).Parse(...) and t.Execute(...), just do:
w.Write([]byte(loginHtml))

注意2:

只有在调用了Request.ParseForm()之后,Request.Form才可用,所以在访问它之前要先调用它。对于POST表单,你可能想使用Request.PostForm

作为替代,你可以使用Request.PostFormValue()方法,如果尚未调用它,它会自动为你执行这个操作:

fmt.Println("username:", r.PostFormValue("username"))
fmt.Println("password:", r.PostFormValue("password"))
英文:

The problem with your original question (which has been edited several times) was that your ParseFiles() function failed, it was not able to read your template file. You didn't know about this because the error it returned you just discarded. Never do that! The least you can do is print the error or call panic(err) if it occurs. Would you have done that, you would have seen the cause immediately.

The login.gtpl file has to be placed in the working directory you start you app from if you specify a relative path. Or specify an absolute path.

You can also put your HTML source into your Go file like this until you sort things out:

t, err := template.New(&quot;&quot;).Parse(loginHtml)
if err != nil {
panic(err)
}
t.Execute(w, nil)
// ... the rest of your code
// At the end of your .go source file (outside of login() func) insert:
const loginHtml = `
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form action=&quot;/login&quot; method=&quot;post&quot;&gt;
Username:&lt;input type=&quot;text&quot; name=&quot;username&quot;&gt;
Password:&lt;input type=&quot;password&quot; name=&quot;password&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;Login&quot;&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
`

Note #1:

Since your HTML template is just a static HTML, in its current form you can simply just send it to the output without building and executing a template from it:

// Instead of calling template.New(...).Parse(...) and t.Execute(...), just do:
w.Write([]byte(loginHtml))

Note #2:

The Request.Form is only available after Request.ParseForm() has been called, so do that prior to accessing it. Also for POST forms you might want to use Request.PostForm instead.

As an alternative you can use the Request.PostFormValue() method which does this for you automatically if it has not yet been called:

fmt.Println(&quot;username:&quot;, r.PostFormValue(&quot;username&quot;))
fmt.Println(&quot;password:&quot;, r.PostFormValue(&quot;password&quot;))

huangapple
  • 本文由 发表于 2015年2月19日 23:20:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/28610030.html
匿名

发表评论

匿名网友

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

确定