我正致力于将我的宠物项目从Python转换为Go,以帮助我熟悉该语言。我目前面临的一个问题是,它正在逃避我的正斜杠。所以它会收到一个字符串,如:
%2flocation%2fto%2fsomething
然后变成
<tr><td><a href="/file?file={{.FullFilePath}}">{{.FileName}}</a></td></tr>
现在,只有当它在链接中时才会这样做(从我读过这个转义是上下文的),所以这就是HTML模板中的行:
func renderTemplate(w http.ResponseWriter, tmpl string) {
t, err := template.ParseFiles(templates_dir+"base.html", templates_dir+tmpl)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if tmpl == "view.html" {
err = t.Execute(w, FileList)
} else {
err = t.Execute(w, nil)
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
如果可能,我如何在模板或代码本身中阻止这种情况?
这就是我的模板功能(是的,我知道它是hackish)
std::cout << static_cast<QDoubleSpinBox*>(ui->InitialValuesTable->cellWidget(2, 1))->value() << std::endl;
答案 0 :(得分:2)
作为.FullFilePath
的值,传递template.URL
类型的值而不是string
,这将告诉html/template
包不要逃避它。
例如:
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>`
输出(在Go Playground上尝试):
<tr><td><a href="/file?file=/location/to/something">something.txt</a></td></tr>
请注意,即使URL中允许使用正斜杠/
,template
包仍会对其进行编码的原因是因为它会分析URL并看到您要包含的值是值一个URL参数(file=XXX
),因此它也对斜杠进行编码(这样您传入的所有内容都将成为file
URL参数值的一部分)。
如果您打算从URL参数获取服务器端的此文件路径,那么template
包的作用是正确的。
但要知道,通过这样做,您将失去阻止代码注入URL的安全性。如果您是提供价值的人并且您知道他们是安全的,那么没有问题。但是,如果数据来自用户输入,请不要这样做。
另请注意,如果您传递整个网址(而不仅仅是其中的一部分),则无需使用template.URL
即可使用(在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>`
另请注意,我认为推荐的方法是将文件路径作为URL路径的一部分而不是参数的值,因此您应该创建这样的URL:
/file/location/to/something
将处理程序(提供文件内容,请参阅this answer作为示例)映射到/file/
模式,当匹配并调用处理程序时,切断{{1}来自路径/file/
的前缀,其余的将是完整的文件路径。如果您选择此选项,您也不会需要r.URL.Path
转换(因为您包含的值不再是网址参数的值):
template.URL
在Go Playground上尝试此操作。
同样非常重要:永远不要在处理函数中解析模板!详情请见:
答案 1 :(得分:0)
好的,所以我找到的解决方案(如果有更好的解决方案请发帖)是基于答案here。
我改变了我正在使用的结构:
a = raw_input("Enter a: ")
b = raw_input("Enter b: ")
print "a + b as strings: %s" % a + b
a = int(a)
b = int(b)
c = a + b
print "a + b as integers: %d" % c
对此:
type File struct {
FullFilePath string
FileName string
}
将html移动到FullFilePath名称中,然后将其放在template.HTML中,这样我生成的每个FullFilePath名称都是这样完成的:
type File struct {
FullFilePath template.HTML
FileName string
}
我的模板文件行已更改为:
file := File{template.HTML("<a href=\"/file?file=" + path + "\"</a>"), f.Name()}