使用 Javascript 在 HTML5 数据属性中转义引号

Posted

技术标签:

【中文标题】使用 Javascript 在 HTML5 数据属性中转义引号【英文标题】:Escape Quotes In HTML5 Data Attribute Using Javascript 【发布时间】:2011-11-07 18:43:22 【问题描述】:

我正在使用 jQuery 的 .data() 来处理自定义 html5 数据属性,其中属性的值需要能够同时包含单引号和双引号:

<p class="example" data-example="She said "WTF" on last night's show.">

我知道在数据属性值中使用像&amp;quot; 这样的字符代码可以使上述工作正常进行,但我不能总是控制值的输入方式。另外,我需要能够在标记中使用 HTML 标签,如下所示:

<p class="example" data-example="
She said "<abbr title="What The F***">WTF</abbr>" on last night's show.
">

如果某种形式的.replace() 是答案,那么它需要在.data() 读取值之前完成——也许通过将它应用于整个&lt;body&gt;

&lt;abbr title="te\'st"&gt;WTF&lt;/abbr&gt; 这样的普通反斜杠转义也不起作用。

理想情况下,这将具有同时工作的灵活性:

data-example="..."data-example='...'

但如果只有一种方式可行,那么我至少可以顺其自然。想法?

更新 - 更多上下文:

我正在为responsejs.com 工作。一个实际的应用可能是只为超过一定宽度的浏览器加载侧边栏(并在浏览器而不是 php 中处理)。以 WordPress 为例,侧边栏可以包含小部件、图像等。PHP 标记中的引号是非问题 b/c,它们在到达浏览器之前会被解析为 HTML。示例:

<aside id="primary" class="sidebar" 

        data-oweb=' 

            <?php dynamic_sidebar( 'primary' ); ?>

        '
    >

    optional default markup for mobile and no-js browsers here

</aside>

【问题讨论】:

javascript 在页面渲染后将无法帮助您修复标记的引号。必须在服务器端完成。 【参考方案1】:

没有办法绕过它,你必须正确地转义值,否则 HTML 无法正确解析。代码解析后不能用Javascript改正,因为这样就已经失败了。

您使用正确的 HTML 编码的示例是:

<p class="example" data-example="She said &quot;&lt;abbr title=&quot;What The F***&quot;&gt;WTF&lt;/abbr&gt;&quot; on last night's show.">

您不能使用反斜杠来转义字符,因为它不是 Javascript 代码。您可以使用 HTML 实体来转义 HTML 代码中的字符。

如果您无法控制数据的输入方式,那么您就完蛋了。你只需要找到一种方法来控制它。

【讨论】:

使用 htmlspecialchars()ENT_QUOTES 来打印它,例如&lt;?php echo(htmlspecialchars($myValue,ENT_QUOTES)) ?&gt;欲了解更多信息:php.net/manual/en/function.htmlspecialchars.php【参考方案2】:

使用 encodeURI 转义 JSON 对象中的引号。使用 decodeURI 解析字符串。

var popup = document.getElementById('popup'),
    msgObj = JSON.parse(decodeURI(popup.dataset.message));

console.log(msgObj);
&lt;a id="popup" href="#" data-message="%7B%22title%22:%22Print%22,%22message%22:%22Printing%20not%20yet%20implemented%22%7D" /&gt;

【讨论】:

相当不错的解决方案。【参考方案3】:

如果它们必须是带有 "' 之类的 HTML 字符串,为什么不为它们制作单独的 HTML 元素:http://jsfiddle.net/N7XXu/。

例如HTML:

<p class="example" data-which="1">a</p>

<p class="example-data" data-which="1">She said "<abbr title="What The F***">WTF</abbr>" on last night's show.</p>

结合以下 JavaScript:

$('.example').each(function() 
    var correspondingElem = $('.example-data[data-which="'
                              + $(this).data('which')
                              + '"]');
    $(this).data('example', correspondingElem.html());
);

alert($('.example').data('example'));

当然,隐藏.example-data 元素。

【讨论】:

谢谢——这很酷,但我需要这个,因为它不会飞。我刚刚用更多上下文更新了这个问题。【参考方案4】:

这是我创建的一个简单工具,可用于对 html 进行编码:

诀窍是逃脱它两次。

我添加了一个额外的 \n 替换来保留多行文本,因为它被 text() 丢弃了。

此外,您需要转义引号以使其对数据属性安全。

<div id="esc"></div>
<textarea id="escinput" placeholder="Enter text"></textarea>
<script>
    $("#escinput").bind("change paste keyup", function()
        $("#esc").text($(this).val().replace(/\n/g,'\\n'));
        $("#esc").text($("#esc").html().replace(/"/g, '&quot;'));
    );            
</script>

这应该创建一个数据属性安全字符串。

你可以在这里测试它:http://jsfiddle.net/SplicePHP/n6HFq/

要将其解码回 html,只需使用:

<script>
    var attr = $("#idOfElement").data('attribute');
    var decoded = $('<textarea/>').html(attr).val();
</script>

【讨论】:

【参考方案5】:

要使其成为正确的 html,您必须转义麻烦的字符。我会用 HTML 实体转义它们。这意味着用于输入此信息的任何工具都必须正确存储它们和/或在后端检索它们的工具必须转义它们。

如果你想在你的 JS 中使用它们,你必须运行一些查找和替换函数来将字符转换回 HTML 和引号。

大多数后端开发语言都有某种“htmlescape/unescape”功能,所以应该不难。

要通过 jQuery 取消转义,可以通过快速 Google 找到以下内容:http://www.naveen.com.au/javascript/jquery/encode-or-decode-html-entities-with-jquery/289

【讨论】:

需要将编码后的字符替换回来-属性值,通过js访问时,已经规范化回纯文本【参考方案6】:

当我使用 data 属性与 PHP 中的 html 元素一起传输一些数据时 对于 JavaScript,我只是在后端使用 base64_encode,然后在客户端使用 base64Decode(input) 来取回数据。这样我就避免了任何逃避狂欢。 我使用的 JavaScript 代码位于这里http://www.webtoolkit.info/

【讨论】:

【参考方案7】:

这有点棘手,但您可以选择带有包含单引号的 data 属性的 dom 对象。诀窍是\\'

<div id="text" data-message="Stanley Kubrick's Oranges">Hello</div>

<script>
    var message = "Stanley Kubrick\\'s Oranges";
    $("#text[data-message='"+message+"']").fadeOut("slow");
</script>

Fiddle

【讨论】:

【参考方案8】:

如果你使用 Lodash,那么你可以使用 _.escape()_.unescape()。它将字符串中的字符 "&"、""、'"' 和 "'" 转换为它们对应的 HTML 实体。

参考:https://lodash.com/docs/#escape

【讨论】:

【参考方案9】:

使用btoa方法设置数据,使用atob方法获取数据:

 $(document).data("test2",btoa('She said "<abbr title="What The F***">WTF<\/abbr>" on last nights show.">'))

或者简单地将字符串作为变量取消引用:

 var stringer = 'She said "<abbr title="What The F***">WTF<\/abbr>" on last nights show.">'

 $(document).data("test2",stringer);

参考文献

HTML5 Living Standard, Web application APIs: Base64 utility methods

【讨论】:

以上是关于使用 Javascript 在 HTML5 数据属性中转义引号的主要内容,如果未能解决你的问题,请参考以下文章

使用 HTML5 + Javascript 将数据字符串保存为文件而不使用 URI [重复]

js自定data-*和jquery的data()用法

在没有文件的情况下在 HTML5 中播放来自 javascript 的音频 - 使用缓冲区

Web 浏览器中的 SQL 数据库存储 Javascript/HTML5

如何通过 javascript/html5 播放 wav 音频字节数组?

将两个日期与从 HTML5 数据中提取的 javascript 进行比较