Golang中HTML模板在POST请求时无法正常工作的问题
Golang中HTML模板在POST请求时无法正常工作的问题 whatarethose.go 文件
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
// request switch
switch r.Method {
case "GET":
fmt.Println("GET")
http.ServeFile(w, r, "whatarethose.html")
case "POST":
// send name and value to html
t, err := template.ParseFiles("whatarethose.html")
if err != nil {
fmt.Println(err)
}
items := struct {
Name string
Value float64
}{
Name: "hi",
Value: 0.1,
}
t.Execute(w, items)
}
}
whatarethose.html 文件
<form name="predict" method="POST" action="/" target="hiddenFrame">
<div class="row half">
<div class="6u">
<input type="text" id="url" class="text" name="url" placeholder="URL"></textarea>
</div>
</div>
<div class="row">
<div class="12u">
<button id="submit" class="button">Submit</button>
</div>
</div>
</form>
<br></br>
<div id="result">
<img id="loader" style="display:none" src="/images/load.gif"></div>
<div id="res">
<p id="info">{{.Name}}<br>{{.Value}}</p>
<img id="demo" src="">
</div>
</div>
以上是我项目中的部分骨架代码。我的网页上有一个表单,提交时会发出 POST 请求。在我的 Go 代码中,我试图将 API 调用的响应作为结构体传回 HTML 页面,以在此处显示:<p id="info">{{.Name}}<br>{{.Value}}</p>。但实际显示的只有字面字符串 {{.Name}} 和 {{.Value}}。然而,当我把 Go 文件中的模板代码移到 GET 情况中或之前时,它可以正常显示任何值,但我没有从 API 调用返回的值,所以我需要在 POST 情况中包含模板代码,但它不起作用。如果有人能告诉我原因以及如何解决这个问题,我将非常感激。谢谢。
更多关于Golang中HTML模板在POST请求时无法正常工作的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这里似乎缺少了一些内容。根据你的示例,以下修改对我有效:
- 在
whatarethose.go中,将t.Execute()替换为t.ExecuteTemplate()。例如:t.ExecuteTemplate(w, "whatarethose", items) - 在
whatarethose.html中,添加{{define}}来访问你的数据。例如:
{{define "whatarethose"}}
<p id="info">{{.Name}}<br>{{.Value}}</p>
<img id="demo" src="">
{{ end }}
编辑:我刚意识到这个帖子已经发布一个月了,可能已经不再相关。抱歉!
更多关于Golang中HTML模板在POST请求时无法正常工作的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题在于你的HTML模板中包含了表单本身,当在POST请求中重新渲染整个页面时,表单会覆盖之前的内容。模板引擎确实在工作,但由于表单仍然存在,它会重新显示模板标签而不是渲染后的值。
以下是修复方案:
修改后的 Go 代码:
func handler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
fmt.Println("GET")
http.ServeFile(w, r, "whatarethose.html")
case "POST":
// 解析结果模板而不是完整页面
t, err := template.ParseFiles("result.html")
if err != nil {
fmt.Println(err)
return
}
items := struct {
Name string
Value float64
}{
Name: "hi",
Value: 0.1,
}
t.Execute(w, items)
}
}
创建新的 result.html 文件:
<div id="result">
<div id="res">
<p id="info">{{.Name}}<br>{{.Value}}</p>
<img id="demo" src="">
</div>
</div>
修改原来的 whatarethose.html 文件:
<form name="predict" method="POST" action="/" target="hiddenFrame">
<div class="row half">
<div class="6u">
<input type="text" id="url" class="text" name="url" placeholder="URL">
</div>
</div>
<div class="row">
<div class="12u">
<button id="submit" class="button">Submit</button>
</div>
</div>
</form>
<br>
<div id="result-container">
<!-- 这里将通过AJAX加载结果 -->
</div>
<iframe name="hiddenFrame" style="display:none"></iframe>
<script>
document.getElementById('submit').addEventListener('click', function(e) {
e.preventDefault();
// 显示加载动画
document.getElementById('loader').style.display = 'block';
// 使用AJAX提交表单
fetch('/', {
method: 'POST',
body: new FormData(document.forms.predict)
})
.then(response => response.text())
.then(html => {
document.getElementById('result-container').innerHTML = html;
document.getElementById('loader').style.display = 'none';
});
});
</script>
或者,如果你想要保持当前结构但修复问题,可以使用条件模板:
修改后的单一模板方案:
func handler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("whatarethose.html")
if err != nil {
fmt.Println(err)
return
}
data := struct {
Name string
Value float64
IsPost bool
}{
Name: "hi",
Value: 0.1,
IsPost: r.Method == "POST",
}
t.Execute(w, data)
}
对应的模板文件:
{{if not .IsPost}}
<form name="predict" method="POST" action="/" target="hiddenFrame">
<div class="row half">
<div class="6u">
<input type="text" id="url" class="text" name="url" placeholder="URL">
</div>
</div>
<div class="row">
<div class="12u">
<button id="submit" class="button">Submit</button>
</div>
</div>
</form>
{{end}}
<br>
<div id="result">
{{if .IsPost}}
<div id="res">
<p id="info">{{.Name}}<br>{{.Value}}</p>
<img id="demo" src="">
</div>
{{end}}
</div>
第一个方案使用单独的模板文件处理POST响应,第二个方案使用条件逻辑在同一个模板中控制显示内容。两种方案都能解决模板标签不被渲染的问题。

