如何在Play模板中避免引号被转义?
我前阵子刚踩过Play模板生成JS的这个坑!你说的@Html()不管用的情况太真实了——因为@Html()只是用来避免HTML实体编码(比如把<转成<),但在<script>标签的JS上下文里,Play的模板引擎还会额外做JS语法层面的转义(比如把双引号转成\"),这时候@Html()就完全无能为力了。
给你几个实用的解决方案,按推荐程度排序:
1. 利用引号嵌套绕过转义(最简单安全)
Play的模板引擎只会转义和外层引号相同的内部引号,所以只要换一种引号包裹JS字符串,就能避免内部引号被转义。比如:
@* 假设你的变量包含双引号 *@ @val userInput = "我刚说:\"这个坑好烦\"" <script> // 用单引号包裹变量,内部双引号不会被转义 let userMsg = '@userInput'; // 最终输出:let userMsg = '我刚说:"这个坑好烦"'; </script>
如果你的字符串里是单引号,就反过来用双引号包裹就行。
2. 使用@Raw()完全跳过转义(谨慎使用)
如果你确实需要输出完全原始的内容(包括和外层相同的引号),可以用@Raw()告诉模板引擎跳过所有转义逻辑。但一定要注意:这个方法有XSS风险,必须确保你的内容是完全可信的,没有恶意代码。
示例:
@val rawJsCode = "var settings = { label: \"直接保留引号\" };" <script> @Raw(rawJsCode) // 最终输出:var settings = { label: "直接保留引号" }; </script>
3. 为什么@Html()解决不了问题?
再啰嗦一句:@Html()的设计目标是处理HTML上下文的实体编码,比如让你在页面上直接显示<div>而不是转义后的<div>。但在JS代码块里,Play的转义逻辑是独立的——它要保证生成的JS语法合法,所以会自动转义引号,这部分逻辑@Html()无法干预。
内容的提问来源于stack exchange,提问作者Arne Claassen
相关产品推荐
相关产品推荐

