Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ResponseWriter为什么以及何时生成原始html?_Html_Templates_Go - Fatal编程技术网

ResponseWriter为什么以及何时生成原始html?

ResponseWriter为什么以及何时生成原始html?,html,templates,go,Html,Templates,Go,我不明白为什么代码正确地生成view.html和post.html数据,但将其全部显示为原始文本。我一直在遵循指南,在构建它的过程中,我认为从Execute函数生成的html将被发送到负责显示它的ResponseWriter,但我得到的错误似乎表明我对Execute的理解或ResponseWriter是错误的 package main import ( "os" "fmt" "time" "bufio" "net/http" "html/temp

我不明白为什么代码正确地生成view.html和post.html数据,但将其全部显示为原始文本。我一直在遵循指南,在构建它的过程中,我认为从Execute函数生成的html将被发送到负责显示它的ResponseWriter,但我得到的错误似乎表明我对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)
}   
主程序包
进口(
“操作系统”
“fmt”
“时间”
“布菲奥”
“net/http”
“html/模板”
)
类型UserPost结构{
名称字符串
关于字符串
后期字符串
}
功能检查(e错误){
如果e!=nil{
fmt.Println(“收到错误…”)
恐慌(e)
}
}
func lineCounter(工作文件*os.File)int{
fileScanner:=bufio.NewScanner(工作文件)
行数:=0
对于fileScanner.Scan(){
行号++
}
返回行计数
}
func加载页(i int)(*UserPost,错误){
Posts,err:=os.Open(“dataf.txt”)
检查(错误)
var PostArray[512]UserPost=parsePosts(Posts,i)
名称:=PostArray[i]。名称
About:=PostArray[i]。关于
PostTime:=PostArray[i]。PostTime
Posts.Close()
return&UserPost{Name:Name[:len(Name)-1],About:About[:len(About)-1],PostTime:PostTime[:len(PostTime)-1]},无
}
func viewHandler(w http.ResponseWriter,r*http.Request){
tmp,err:=os.Open(“dataf.txt”)
检查(错误)
num:=(行计数器(tmp)/3)
tmp.Close()
对于i:=0;i对于提示的i:=0;i,这是因为您尚未设置内容类型。引用自:

如果您不自己设置内容类型,首先调用
ResponseWriter.Write()
将调用以猜测要设置的内容。如果您发送的内容以
”开头,则不会将其检测为HTML,但将设置
“text/plain;charset=utf-8”
(指示)浏览器可以将内容显示为文本,而不尝试将其解释为HTML)

例如,如果内容以
开头,则会自动设置内容类型
”text/html;charset=utf-8“
,并且无需进一步操作

但是,如果您知道要发送什么,就不要依赖自动检测,而且自己设置要比在其上运行检测算法快得多,因此只需在写入/发送任何数据之前添加这一行:

w.Header().Set("Content-Type", "text/html; charset=utf-8")
并使您的
post.html
模板成为完整、有效的html文档


还有一条建议:在代码中,您完全忽略了检查返回的错误。不要这样做。您至少可以在控制台上打印它们。如果不忽略错误,您将为自己节省大量时间。

正如所暗示的,这是因为您没有设置内容类型。引用自:

如果您不自己设置内容类型,首先调用
ResponseWriter.Write()
将调用以猜测要设置的内容。如果您发送的内容以
”开头,则不会将其检测为HTML,但将设置
“text/plain;charset=utf-8”
(指示)浏览器可以将内容显示为文本,而不尝试将其解释为HTML)

例如,如果内容以
开头,则会自动设置内容类型
”text/html;charset=utf-8“
,并且无需进一步操作

但是,如果您知道要发送什么,就不要依赖自动检测,而且自己设置要比在其上运行检测算法快得多,因此只需在写入/发送任何数据之前添加这一行:

w.Header().Set("Content-Type", "text/html; charset=utf-8")
并使您的
post.html
模板成为完整、有效的html文档


还有一条建议:在代码中,您完全忽略了检查返回的错误。不要这样做。您至少可以在控制台上打印它们。如果不忽略错误,您将为自己节省大量时间。

您没有在HTTP响应头中指定内容类型。请尝试添加内容类型头。就像@josh一样如前所述,您需要设置内容类型,而不是源访问控制。因此,如果您希望输出为html,您需要执行以下操作:w.Header()。设置(“内容类型”,“文本/html”)“访问控制允许源”不是“内容类型”,因此您的“无更改”这是意料之中的。joshlf要求提供内容类型,他是对的。进行检测的函数是DetectContentType(实现)。这是一个非常简单的函数-基本上它只是尝试与非常简单的基于文本的签名列表进行匹配,并查看是否有匹配。HTML签名(请参阅)不要包含
,因为这些是您的资源开头的标记,这是它需要匹配的,以便正确检测内容类型(因为它只关注前几个字节)。我敢打赌,如果您发送的文档以
开头,则
// 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)
w.Header().Set("Content-Type", "text/html; charset=utf-8")