英文:
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's the simple form from astaxie's book
when I try '/login' , I get
No Data received { Unable to load the webpage because the server sent no data. Error code: ERR_EMPTY_RESPONSE }
Here's the code:
**main.go**
package main
import (
"fmt"
"html/template"
"net/http"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello astaxie!") // write data to response
}
func login(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //get request 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()
// logic part of log in
fmt.Println("username:", r.PostFormValue("username"))
fmt.Println("password:", r.PostFormValue("password"))
}
}
func main() {
http.HandleFunc("/", sayhelloName) // setting router rule
http.HandleFunc("/login", login)
http.ListenAndServe(":9090", nil) // setting listening port
}
#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>
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("").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 = `
<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>
`
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("username:", r.PostFormValue("username"))
fmt.Println("password:", r.PostFormValue("password"))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论