在一个非常基本的手写网页(没有js,样式表等)中,我有一些静态html,其部分看起来像这样。
<li style="font-size:200%; margin-bottom:3vh;">
<a href="http://192.168.1.122:8000">
Reload HMI
</a>
</li>
我正在使用Go的http.ListenAndServe服务该页面。出现的内容如下:
<li style="font-size:200%!;(MISSING) margin-bottom:3vh;">
<a href="http://192.168.1.122:8000">
Reload HMI
</a>
</li>
请注意样式属性已更改。
服务器实现也是基本的。它以goroutine的形式启动:
// systemControlService provides pages on localhost:8003 that
// allow reboots, shutdowns and restoring configurations.
func systemControlService() {
info("Launching system control service")
http.HandleFunc("/", controlPage)
log.Fatal(http.ListenAndServe(":8003", nil))
}
// loadPage serves the page named by title
func loadPage(title string) ([]byte, error) {
filename := "__html__/" + title + ".html"
info(filename + " requested")
content, err := ioutil.ReadFile(filename)
if err != nil {
info(fmt.Sprintf("error reading file: %v", err))
return nil, err
}
info(string(content))
return content, nil
}
// controlPage serves controlpage.html
func controlPage(w http.ResponseWriter, r *http.Request) {
p, _ := loadPage("controlpage")
fmt.Fprintf(w, string(p))
}
在上面的功能loadPage()
中,info
是一个记录调用。对于调试,我只是在返回controlpage.html
的内容之前调用它。日志条目显示此时还没有被处理,因此问题基本上必须在ListenAndServe内。
我在http
的Go文档中找不到任何适用的内容。我不知道这是怎么回事。任何帮助表示赞赏。
答案 0 :(得分:5)
您的代码存在几个问题(包括您可以使用http.FileServer
提供静态内容时根本就存在的事实,以及您之前将整个响应读入[]byte
的事实)发送回来而不是流式传输),但是 main 就是这样的:
fmt.Fprintf(w, string(p))
Fprintf
的第一个参数是 format字符串。它可以替换以%
开头的格式字符串中的内容。要将[]byte
写给写程序,您不需要fmt包,因为您不想格式化任何东西。 w.Write()足够好。 fmt.Fprint
也可用,但完全没有必要;它会做多余的工作,无济于事,然后致电w.Write
。
答案 1 :(得分:1)
问题在于fmt.Fprintf
会将响应主体解释为带有%替换的格式字符串。解决此问题的一种方法是提供格式字符串:
fmt.Fprintf(w, "%s", p)
无需使用这种方法将p
转换为字符串。
此处的目标是将字节写入响应编写器。将字节写入响应编写器(或任何其他io.Writer)的惯用方法和最有效的方法是:
w.Write(p)
fmt
软件包不适合在这里使用,因为不需要格式化。
答案 2 :(得分:-2)
您可以尝试一下吗,请注意 Fprint 而不是 Fprintf
func controlPage(w http.ResponseWriter, r *http.Request) {
p, _ := loadPage("controlpage")
fmt.Fprint(w, string(p))
}