从data属性读取JSON时HTML实体转字符致解析异常问题
解决jQuery获取data属性时HTML实体转义导致JSON解析失败的问题
我之前也踩过一模一样的坑!当你用$(element).data('whatever')或者$(element).attr('data-whatever')读取包含HTML实体的JSON字符串时,浏览器会自动把实体解码成对应字符,比如"变成",直接破坏了原本合法的JSON结构,自然会导致解析报错。
下面给你几个靠谱的解决思路:
方法1:用原生dataset获取原始未解码字符串
原生DOM的dataset属性会直接返回data属性的原始文本值,不会自动解码HTML实体,这是最直接的解决方案。举个例子:
// 假设你的元素结构是这样的 // <div id="eventElem" data-events='["Oberlin City Club: Opera Preview","Documentary Screening &quot;Still Dreaming: Frances Walker at 93&quot;"]'></div> const elem = document.getElementById('eventElem'); const rawJsonStr = elem.dataset.events; // 拿到未解码的原始JSON字符串 const parsedData = JSON.parse(rawJsonStr); // 现在可以正常解析了
方法2:提前对JSON做双重转义(适合必须用jQuery的场景)
如果项目依赖jQuery,那可以在设置data属性时就做双重转义:把原本JSON里的"先转成",再把&转成&。这样浏览器解码一次后,会得到JSON合法的",不管用attr()还是data()都能正常解析。
比如后端输出的HTML要写成这样:
<div data-events='["Oberlin City Club: Opera Preview","Documentary Screening &quot;Still Dreaming: Frances Walker at 93&quot;"]'></div>
前端读取时直接解析即可:
const jsonStr = $('#eventElem').attr('data-events'); const events = JSON.parse(jsonStr);
方法3:后端提前做好HTML实体编码(终极稳妥方案)
从根源上解决的话,后端在生成JSON并输出到data属性前,先对整个JSON字符串做HTML实体编码。这样前端拿到的是完全安全的字符串,不管用哪种方式读取都能直接解析。
举个PHP后端的例子:
$events = ["Oberlin City Club: Opera Preview", "Documentary Screening \"Still Dreaming: Frances Walker at 93\""]; $jsonStr = json_encode($events); // 对JSON字符串做HTML实体编码,确保特殊字符被正确转义 $safeJson = htmlspecialchars($jsonStr, ENT_QUOTES); // 输出到页面 echo "<div data-events='{$safeJson}'></div>";
补充:为什么data()和attr()会出问题?
jQuery的data()方法会自动识别并解析看起来像JSON的属性值,但在这之前,浏览器已经把HTML实体解码了,导致JSON结构被破坏;而attr()虽然不会自动解析,但它拿到的也是浏览器解码后的字符串,所以同样会出问题。原生dataset则跳过了浏览器的解码步骤,直接读取属性的原始文本,完美避开这个坑。
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

