Twig中json_encode处理含特殊字符空格字符串及传递到Vue.js的方法
问题原因
你遇到的JSON截断问题核心有两个:
- 自定义HTML属性没有用双引号包裹,浏览器遇到空格会直接判定属性值结束,导致内容被截断
- 没有对JSON内容做HTML属性安全转义,特殊字符也会触发属性解析异常
解决方案
方案1:修复现有属性传值写法
仅需修改两处即可解决截断问题:给属性加双引号包裹,搭配Twig的html_attr转义过滤器,同时给json_encode加参数避免特殊字符解析异常:
{# 原有翻译逻辑不变 #} {% set snippets = { string1: 'string1'|trans, string2: 'string2'|trans, } %} {# 用双引号包裹属性值,加上属性转义过滤器 #} <div id="app" snippet="{{ snippets|json_encode(constant('JSON_UNESCAPED_UNICODE'))|e('html_attr') }}"> <demo></demo> </div> <script> let snippetJSON = document.getElementById('app').getAttribute('snippet'); // 此时可以拿到完整JSON,用JSON.parse转成对象即可使用 console.log(JSON.parse(snippetJSON)); </script>
方案2:更优的JS变量直接赋值(推荐)
不需要通过HTML属性中转,直接在script标签内输出JSON,完全规避HTML属性解析的各类坑,更适合给Vue实例使用:
{% set snippets = { string1: 'string1'|trans, string2: 'string2'|trans, } %} <div id="app"> <demo></demo> </div> <script> // 直接输出JSON到JS变量,raw过滤器避免Twig自动转义双引号 const snippets = {{ snippets|json_encode(constant('JSON_UNESCAPED_UNICODE'))|raw }}; // 可直接传入Vue实例使用,不需要额外的读取属性、反序列化操作 const app = Vue.createApp({ data() { return { snippets: snippets } } }) </script>
该方案没有HTML属性解析的兼容性问题,性能更好,也省去了多余的序列化/反序列化步骤,是传递变量到Vue的最优选择。
注意事项
- 如果你的Twig开启了全局自动转义,直接输出JSON到script标签必须加
raw过滤器,否则双引号会被转义为"导致JS语法错误 JSON_UNESCAPED_UNICODE参数可以避免中文、小语种特殊字符被转义为Unicode编码,不影响JSON解析的同时可读性更高
内容的提问来源于stack exchange,提问作者willoid
相关产品推荐
相关产品推荐

