我不明白为什么代码会正确生成view.html和post.html数据,但全部显示为原始文本。我一直在这里遵循指南,并且在构建它时,我认为将从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文件读取。
如提示所示,这是因为您尚未设置内容类型。引用自http.ResponseWriter:
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"会进行设置(“指示”浏览器将内容显示为文本,而不尝试将其解释为HTML)。
ResponseWriter.Write()
http.DetectContentType()
"<form>"
"text/plain; charset=utf-8"
"<html>"例如,如果内容以开头,则内容类型"text/html; charset=utf-8"将自动设置,并且无需进一步操作即可工作。
"<html>"
"text/html; charset=utf-8"
但是,如果您知道要发送的内容,请不要依赖自动检测,而且,自己设置它比在其上运行检测算法要快得多,因此只需在写入/发送任何数据之前添加以下行即可:
w.Header().Set("Content-Type", "text/html; charset=utf-8")
并使post.html模板成为完整的有效HTML文档。
Also another piece of advice: in your code you religiously omit checking returned errors. Don’t do that. The least you could do is print them on the console. You will save a lot of time for yourself if you don’t omit errors.