Da der Wert von .FullFilePath
, einen Wert vom Typ passieren template.URL
statt string
, die die html/template
Paket sagen wird, es nicht zu entkommen.
Zum Beispiel:
func main() {
t := template.Must(template.New("").Parse(templ))
m := map[string]interface{}{
"FileName": "something.txt",
"FileFullPath": template.URL("/location/to/something"),
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
}
const templ = `<tr><td><a href="/file?file={{.FileFullPath}}">{{.FileName}}</a></td></tr>`
Output (versuchen Sie es auf dem Go Playground):
<tr><td><a href="/file?file=/location/to/something">something.txt</a></td></tr>
Beachten Sie, dass, obwohl nach vorn /
Schrägstriche sind in URLs erlaubt, den Grund, warum die template
Paket kodiert noch Das liegt daran, dass es die URL analysiert und erkennt, dass der Wert, den Sie angeben möchten, der Wert eines URL-Parameters ist (file=XXX
), und so werden auch die Schrägstriche codiert (so dass alles, was Sie übergeben, ist) Teil des Wertes des URL-Parameters file
).
Wenn Sie diesen Dateipfad auf der Serverseite von URL-Parametern erwerben möchten, dann ist das template
-Paket der richtige und richtige Weg.
Aber wissen Sie, dass Sie dadurch die Sicherheit verlieren, die die Code-Injektion in URLs verhindert. Wenn Sie die Werte angeben und wissen, dass sie sicher sind, gibt es kein Problem. Wenn die Daten jedoch beispielsweise von einer Benutzereingabe stammen, tun Sie dies nie.
Beachten Sie auch, dass, wenn Sie die gesamte URL (und nicht nur ein Teil davon) übergeben, wird es ohne template.URL
arbeiten (versuchen Sie diese Variante auf der Go Playground):
func main() {
t := template.Must(template.New("").Parse(templ))
m := map[string]interface{}{
"FileName": "something.txt",
"FileURL": "/file?file=/location/to/something",
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
}
const templ = `<tr><td><a href="{{.FileURL}}">{{.FileName}}</a></td></tr>`
Beachten Sie auch, dass die empfohlene Art und Weise meiner Meinung nach wäre es, den Dateipfad als Teil des URL-Pfad enthalten und nicht als Wert eines Parameters, so stattdessen sollten Sie Urls wie folgt erstellen:
/file/location/to/something
Karte Handler (die die Datei dient Inhalt, siehe this answer als Beispiel) zu dem /file/
Muster, und wenn es übereinstimmt und Ihr Handler aufgerufen wird, schneiden Sie das /file/
Präfix aus dem Pfad r.URL.Path
, und der Rest wird der vollständige Dateipfad sein. Wenn Sie diese Option auswählen, werden Sie auch nicht brauchen die template.URL
Umwandlung (weil der Wert, den Sie enthalten kein Wert eines URL-Parameters ist mehr):
func main() {
t := template.Must(template.New("").Parse(templ))
m := map[string]interface{}{
"FileName": "something.txt",
"FileFullPath": "/location/to/something",
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
}
const templ = `<tr><td><a href="/file{{.FileFullPath}}">{{.FileName}}</a></td></tr>`
die Sie interessieren auf dem Go Playground.
Auch sehr wichtig: Templates nie in Ihren Handler-Funktionen analysieren! Details siehe:
It takes too much time when using "template" package to generate a dynamic web page to client in golang
Mögliches Duplikat [auto Flucht in HTML-Vorlage vermeiden] (http://stackoverflow.com/questions/36980049/avoid-auto-escape-in-html-template) – icza
@ Icza, danke, dass Sie mich auf diesen Link verwiesen haben, aber ich kann nicht sehen, wie ich diese Lösung hier umsetzen kann. Ich bin zugegebenermaßen immer noch ein Noob, vielleicht deshalb. Ich habe am Ende eine andere Frage gefunden, deren Lösung mir geholfen hat, also habe ich das hier gepostet. – basica
Siehe meine Antwort unten. – icza