如何防止http.ListenAndServe更改静态输出中的样式属性? [重复]
This question already has an answer here:
In a very rudimentary handwritten web page (no js, stylesheets, etc) I have some static html with a section that looks like this.
<li style="font-size:200%; margin-bottom:3vh;">
<a href="http://192.168.1.122:8000">
Reload HMI
</a>
</li>
I'm using Go's http.ListenAndServe to serve the page. What's coming out looks like this:
<li style="font-size:200%!;(MISSING) margin-bottom:3vh;">
<a href="http://192.168.1.122:8000">
Reload HMI
</a>
</li>
Note the altered style attribute.
The server implementation is also rudimentary. It's launched as a 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))
}
In func loadPage()
above, info
is a logging call. For debug, I'm calling it just before returning the content of controlpage.html
. The log entry shows it's not mangled at that point, so the problem pretty much has to be within ListenAndServe.
I'm not finding anything in the Go docs for http
that seems applicable. I have no idea what's going on here. Any help appreciated.
</div>
Can you try this, note Fprint rather than Fprintf
func controlPage(w http.ResponseWriter, r *http.Request) {
p, _ := loadPage("controlpage")
fmt.Fprint(w, string(p))
}
There are several problems with your code (including the fact that it exists at all when you could use http.FileServer
to serve static content, and the fact that you read the whole response into a []byte
before sending it back instead of streaming it) but the main one is this:
fmt.Fprintf(w, string(p))
Fprintf
's first argument is a format string. Replacing things in the format string that start with %
is what it does. To write a []byte
to a writer you don't need the fmt package, because you don't want to format anything. w.Write() is good enough. fmt.Fprint
is also available but completely unnecessary; it will do extra work that amounts to nothing and then call w.Write
.
The problem is that fmt.Fprintf
is interpreting the response body as a format string with % substitutions. One way to fix this is to supply a format string:
fmt.Fprintf(w, "%s", p)
There's no need to convert p
to a string with this approach.
The goal here is to write bytes to the response writer. The idiomatic and most efficient way to write bytes to a response writer (or any other io.Writer) is:
w.Write(p)
The fmt
package is not appropriate to use here because no formatting is required.