【问题标题】:jQuery (or JS) decodes HTML character entity in stringjQuery(或 JS)解码字符串中的 HTML 字符实体
【发布时间】:2015-11-17 18:44:12
【问题描述】:

我正在尝试使用 jQuery 和 JSON 响应中返回的字符串数组中的选项值动态填充 <select> 元素。选项值之一是Joe's Cafe,解码后是Joe's Cafe。但是,当我使用以下代码时:

$.each(optionVals, function(idx, elem) {
    $('#restaurant').append('<option value="' + elem + '">' + elem + '</option>');
});

相应的选项不是我所期望的。我看到了:

<option value="Joe's Cafe">Joe's Cafe</option>

而不是这个:

<option value="Joe&#39;s Cafe">Joe&#39;s Cafe</option>

如何防止jQuery在.append()操作中解码HTML实体&amp;#39;?我检查了 JSON 响应,HTML 实体完好无损。我在加载选项后检查了源代码,并且 HTML 实体已被解码为单引号 '

【问题讨论】:

  • 您是使用旧的“查看源代码”(在许多浏览器中为 Ctrl+U)还是通过 DOM 窗格检查实际的 HTML?
  • @ÁlvaroGonzález 我使用 Chrome 的开发人员工具进行了检查。 Good ol' View Source 不会显示 HTML 源代码的动态部分。
  • 那就是问题所在:您看不到实际的 HTML。不确定 Chrome,但如果您右键单击选择并选择“查看所选源”,Firefox 会显示实际 生成的 HTML。
  • 在 Chrome、Firefox 和 Microsoft Edge 中检查...所有三个都将实际生成的 HTML 显示为单引号,而不是 HTML 实体 &amp;#39;

标签: javascript jquery json decode html-entities


【解决方案1】:

如何防止jQuery在.append()操作中解码HTML实体&amp;#39;

你不能,因为它不是。

jQuery 正在生成一些 HTML,然后让 浏览器 将其转换为 DOM。然后,它将该 DOM 片段附加到表示该页面的文档 DOM。

当您使用 DOM 检查器检查 DOM(或当您使用 innerHTML 将其转换为字符串时)时,您正在将 DOM 序列化为 HTML。此时浏览器不知道(因为它没有跟踪,因为它不需要)DOM 中的撇号来自文字撇号还是字符引用。它用来决定如何表示字符的算法使用文字算法(当它可以使用多 1 个可读字符时,使用 5 个字符的代码是没有意义的)。

&lt;option value="Joe's Cafe"&gt;Joe's Cafe&lt;/option&gt;&lt;option value="Joe&amp;#39;s Cafe"&gt;Joe&amp;#39;s Cafe&lt;/option&gt; 是在 HTML 中编写完全相同的两种不同方式。你得到的应该无关紧要。


在 HTML 中可能是相同的东西,但存储在数据库中时完全不同。

听起来您希望表单将字符串Joe&amp;#39;s Cafe 提交给服务器。

&lt;option value="Joe&amp;#39;s Cafe"&gt;Joe&amp;#39;s Cafe&lt;/option&gt; 不会这样做

这需要:value="Joe&amp;amp;#39;s Cafe"

现在您可以通过合理地生成 DOM 而不是将字符串混合在一起来实现这一点(因为当您将字符串混合在一起时,HTML 中具有特殊含义的字符会被视为具有该特殊含义)。

$('#restaurant').append(
    $("<option />").val(elem).text(elem)
);

然而您的意思是数据中包含原始撇号会破坏您的 SQL。

这意味着您很容易受到SQL injection 攻击,并且真正的解决方案是修复这个服务器端

请参阅How can I prevent SQL-injection in PHP? 或查看如何使用准备好的语句来防止您在服务器上使用的任何编程语言中的 SQL 注入。

【讨论】:

  • 在 HTML 中可能是同一个东西,但在数据库中存储时就完全不同了。
  • @Stewartside — 更新了答案。你问错问题了。
  • 很好,对我来说,这只是您的原始答案,似乎缺乏解决问题的方法,而只是掩盖了它为什么这样做。 +1
  • @Stewartside — 这是因为原始问题中没有实际问题。您在问如何将某些东西转换为完全相同的状态,这不是问题。 :)
  • @Quentin 有趣的是注意到(并了解到)将字符串混合在一起会导致 HTML 实体被视为其表示。因此,您的解决方法非常有效。关于 SQL 注入攻击的漏洞,服务器端代码已经降低了这种风险,但我很欣赏它的警报!
【解决方案2】:

为了避免 HTML 实体被解码,您可以在字符串中将 &amp;amp; 全局替换为 &amp;amp;

var optionVals = ["Joe&#39;s Cafe"];
$.each(optionVals, function(idx, elem) {
    elem = elem.replace(/&/g, "&amp;");
    $('#restaurant').append('<option value="' + elem + '">' + elem + '</option>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="restaurant"></select>

【讨论】:

  • @Magicprogfr 我选择了第二个答案,但由于您的回答,我意识到解决此问题的方法不止一种,
猜你喜欢
  • 2018-12-23
  • 2019-01-08
  • 2016-06-18
  • 2017-07-05
  • 2023-03-11
  • 2014-02-15
  • 2011-05-12
  • 2013-09-04
  • 1970-01-01
相关资源
最近更新 更多