我不明白为什么代码正确生成view.html和post.html数据,但将其全部显示为原始文本。我一直在关注指南here,当我构建它时,我认为来自Execute函数的生成的html将被发送到ResponserWriter,它将处理它的显示,但我似乎得到的错误似乎表明我对Execute的理解或者ResponseWriter是错误的。
package main
import (
"os"
"fmt"
"time"
"bufio"
"net/http"
"html/template"
)
type UserPost struct {
Name string
About string
PostTime string
}
func check(e error) {
if e != nil {
fmt.Println("Error Recieved...")
panic(e)
}
}
func lineCounter(workingFile *os.File) int {
fileScanner := bufio.NewScanner(workingFile)
lineCount := 0
for fileScanner.Scan() {
lineCount++
}
return lineCount
}
func loadPage(i int) (*UserPost, error) {
Posts,err := os.Open("dataf.txt")
check(err)
var PostArray [512]UserPost = parsePosts(Posts,i)
Name := PostArray[i].Name
About := PostArray[i].About
PostTime := PostArray[i].PostTime
Posts.Close()
return &UserPost{Name: Name[:len(Name)-1], About: About[:len(About)-1], PostTime: PostTime[:len(PostTime)-1]}, nil
}
func viewHandler(w http.ResponseWriter, r *http.Request) {
tmp,err := os.Open("dataf.txt")
check(err)
num := (lineCounter(tmp)/3)
tmp.Close()
for i := 0; i < num; i++ {
p, _ := loadPage(i)
t, _ := template.ParseFiles("view.html")
t.Execute(w, p)
}
p := UserPost{Name: "", About: "", PostTime: ""}
t, _ := template.ParseFiles("post.html")
t.Execute(w, p)
}
func inputHandler(w http.ResponseWriter, r *http.Request) {
Name := r.FormValue("person")
About := r.FormValue("body")
PostTime := time.Now().String()
filePaste,err := os.OpenFile("dataf.txt", os.O_RDWR | os.O_CREATE | os.O_APPEND | os.SEEK_END, 0666)
check(err)
filePaste.WriteString(Name+"~\n")
filePaste.WriteString(About+"~\n")
filePaste.WriteString(PostTime+"~\n")
filePaste.Close()
fmt.Println("Data recieved: ", Name,About,PostTime)
http.Redirect(w, r, "/#bottom", http.StatusFound) //Use "/#bottom" to go to bottom of html page.
}
//os.File is the file type.
func parsePosts(fileToParse *os.File,num int) [512]UserPost {
var buffer [512]UserPost
reader := bufio.NewReader(fileToParse)
//This For loop reads each "forum post" then saves it to the buffer, then iterates to the next.
for i := 0;i <= num; i++ {
currentPost := new(UserPost)
str, err := reader.ReadString('~')
check(err)
currentPost.Name = str
//I search for '~' because my files save the end of reading line with that, so i can keep formatting saved (\n placement).
str2, err2 := reader.ReadString('~')
check(err2)
currentPost.About = str2
str3, err3 := reader.ReadString('~')
check(err3)
currentPost.PostTime = str3
buffer[i] = *currentPost
}
return buffer
}
func main() {
fmt.Println("Listening...")
http.HandleFunc("/", viewHandler)
http.HandleFunc("/post/", inputHandler)
http.ListenAndServe(":8080", nil)
}
view.html
<h4>{{.Name}}</h4>
<font size="3">
<div>{{printf "%s" .About}}</div>
</font>
<br>
<font size="2" align="right">
<div align="right">{{.PostTime}}</div>
</font>
post.html
<form action="/post/" method="POST">
<div><textarea name="person" rows="1" cols="30">{{printf "%s" .Name}}</textarea></div>
<div><textarea name="body" rows="5" cols="100">{{printf "%s" .About}}</textarea></div>
<div><input type="submit" value="Submit"></div>
<a name="bottom"></a>
</form>
我目前正在读取空的dataf.txt文件。
答案 0 :(得分:3)
正如所暗示的那样,因为您还没有设置内容类型。引自http.ResponseWriter
:
// Write writes the data to the connection as part of an HTTP reply.
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
// before writing the data. If the Header does not contain a
// Content-Type line, Write adds a Content-Type set to the result of passing
// the initial 512 bytes of written data to DetectContentType.
Write([]byte) (int, error)
如果您未自行设置内容类型,请先致电ResponseWriter.Write()
,然后致电http.DetectContentType()
猜猜要设置的内容。如果您发送的内容以"<form>"
开头,则不会被检测为HTML,但会设置"text/plain; charset=utf-8"
(其中&#34;指示&#34;浏览器将内容显示为文本,而不是试图将其解释为HTML)。
如果内容以"<html>"
开头,则内容类型"text/html; charset=utf-8"
将自动设置,无需进一步操作即可生效。
但是,如果您知道自己要发送的内容,请不要依赖自动检测,自行设置也要比在其上运行检测算法快得多,所以只需添加此行即可在写/发送任何数据之前:
w.Header().Set("Content-Type", "text/html; charset=utf-8")
还可以使您的post.html
模板成为完整有效的HTML文档。
另外一条建议:在你的代码中,你虔诚地忽略了检查返回的错误。不要这样做。你能做的最少就是在控制台上打印它们。如果你不排除错误,你将为自己节省很多时间。