
Beego 的 HTML 模板默认会对变量进行上下文敏感转义,当 URL 字符串被插入 data-url 等属性时,会二次 HTML 编码 & 为 &,导致请求失效;正确做法是使用 str2html 函数绕过转义,或改用 urlquery 等更语义化的模板函数。
beego 的 html 模板默认会对变量进行上下文敏感转义,当 url 字符串被插入 data-url 等属性时,会二次 html 编码 & 为 &,导致请求失效;正确做法是使用 str2html 函数绕过转义,或改用 urlquery 等更语义化的模板函数。
在 Beego 中,模板引擎(基于 Go 标准库 html/template)严格遵循「上下文感知转义」原则:当变量出现在 HTML 属性值中(如 <table data-url="{{.querystring}}">),引擎会自动对特殊字符(包括 <code>&, , <code>> 等)执行 HTML 实体编码,以防止 XSS 攻击。这本是安全特性,但当你的 .querystring 已是预编码的完整 URL(如 /filetranslog/getlogs?sdate=...&edate=...),重复转义就会将 & 变成 &,最终导致后端无法正确解析查询参数。
✅ 正确解决方案:使用 str2html
Beego 内置了 str2html 模板函数,其作用是将字符串标记为已信任的 HTML 片段,从而跳过自动转义。它不是“解码”,而是告诉模板引擎:“这段内容已由开发者确保安全,请原样输出”。
修改你的模板如下:
@@######@@同时,确保控制器中传递的是原始 URL 字符串(而非双重编码后的)——你当前代码中已手动编码了空格和冒号(%20, %3A),这是合理的,因为 sdate=2016-11-13 00:00 中的空格必须编码。但注意:不要对 & 手动编码为 %26,应保留为字面量 &,由 str2html 原样透传。
? 验证技巧:在浏览器中右键「查看页面源代码」,确认
data-url的值中&未被转义为&。
⚠️ 注意事项与替代方案
str2html≠ 安全豁免:仅当.querystring来源可信(如服务端拼接、白名单路径)时才可使用。若 URL 含用户输入,需先做严格校验(如正则匹配/^\/filetranslog\/getlogs\?.+$/)再透出。-
更推荐:用
@@######@@@@######@@urlquery拼接参数(语义更清晰、更安全):其中
urlquery是 Beego 内置函数,会自动对每个参数值执行url.QueryEscape,并用&连接,避免手动编码错误。 避免滥用
{{.querystring | safe}}:Beego 不支持 Go 模板的safe函数(template.HTML类型需显式转换),强行使用会导致编译错误或静默失败。
? 总结
| 场景 | 推荐方式 | 说明 |
|---|---|---|
| 已预编码的完整 URL(可信来源) | {{str2html .querystring}} |
最简直接,适用于你当前案例 |
| 动态拼接查询参数 | {{urlquery .param1 .param2}} |
更安全、可读性高,推荐新项目采用 |
| 需嵌入 JS 变量 | var url = {{str2html .querystring | js}}; |
结合 js 过滤器防 XSS,适用于 <script></script> 内 |
只要确保数据来源可控,并选用合适的模板函数,就能在保障安全的前提下,精准控制 Beego 模板中的 URL 输出行为。
<!-- ✅ 正确:在 data-url 中使用 str2html -->
// logcontroller.go this.Data["sdate"] = "2016-11-13 00:00" this.Data["edate"] = "2016-12-13 23:59" this.Data["trans_type"] = "2"
<!-- filetrans.html -->
data-url="/filetranslog/getlogs?{{urlquery .sdate .edate .trans_type}}"











