尽管使用 htmlspecialchars 对单引号进行编码,JavaScript 仍然抱怨这些引号需要在函数调用中转义

Posted

技术标签:

【中文标题】尽管使用 htmlspecialchars 对单引号进行编码,JavaScript 仍然抱怨这些引号需要在函数调用中转义【英文标题】:Despite single quotes being encoded using htmlspecialchars, JavaScript is still complaining that these quotes need to be escaped in the function call 【发布时间】:2021-01-10 21:09:03 【问题描述】:

发生了一些奇怪的事情,我被难住了。

我有一个基本上看起来像这样的链接:

<a href="javascript:uploadVariantPicture('size:&#039;test2&#039');">Link</a>

如您所见,我正在使用参数“size:'test2'”调用函数uploadVariantPicture。

但是,当我实际单击该链接时,JavaScript 会抱怨两个编码的单引号没有被转义。我收到以下错误:

SyntaxError:意外的标识符“test2”。期望 ')' 结束参数列表。

如果我解码两个编码的单引号并使用反斜杠转义它们,则函数调用成功。但问题是我需要对其进行编码。我不能让它不编码并转义引号。这不适用于我的情况。

非常感谢任何帮助。我很困惑。

【问题讨论】:

你能详细说明一下吗?我不知道你到底是什么意思。 ***.com/q/65313841/1048572 html 解码 href 属性值时,你会得到 js 代码 uploadVariantPicture('size:'test2'');。这显然是无效的。 我没有解码它。我把它编码了。那么为什么浏览器在 js 调用中将其解释为文字单引号呢? 你已经编写了 HTML,当它被解析成 DOM 时,实体转义被解码。 【参考方案1】:

HTML 字符实体和转义符在解析源代码时被 HTML 解析器替换。对于引号,它允许在 HTML 属性中包含用于引用源中的属性值的相同类型的引号。

例如

 <element attribute="&quot;">
 <element attribute='&#039;'>

在源代码中会分别产生"(双引号)和'(单引号)的属性值,尽管它们是用于在HTML源代码中引用属性值的分隔符。

因此

 <a href="javascript:uploadVariantPicture('size:&#039;test2&#039');">Link</a>

会产生一个href的属性值

  javascript:uploadVariantPicture('size:'test'');

在 HTML 解析器删除外部双引号之后。

选项可以包括在href 值内适当地转义双引号(HTML &amp;quot;)(这取决于uploadVariantPicture 接受的语法),包括在帖子中提到的单引号之前的反斜杠转义,或者不完全使用 javascript: 伪协议,支持在 JavaScript 中添加事件监听器。

强烈建议不要使用javascript: 伪协议 - 基本上这是对 HTML3 的保留。

【讨论】:

使用 javascript: 有什么本质上的错误吗?很适合我的情况。 由于能够执行任意 javascript 代码的安全风险以及 javascript: 实际上不是协议这一事实,它失宠了。在这个时间点上,我认为它更被视为过时的用法,因为有更现代的方法来做同样的事情,开发出来是为了不再需要使用 javascript:【参考方案2】:

考虑使用 JavaScript 正确附加事件处理程序,这样您就不必担心转义问题,也不必依赖全局对象的污染来使脚本工作:

const uploadVariantPicture = (arg) => console.log(arg);

document.querySelector('a').addEventListener('click', () => 
  uploadVariantPicture("size:'test2'");
);
&lt;a&gt;Link&lt;/a&gt;

我想不出任何情况下内联处理程序比addEventListener 更可取,除非您故意尝试利用 XSS 漏洞。

【讨论】:

如果我在调用中编码了双引号,这仍然有效吗? 当然,只要uploadVariantPicture('size:"test2"'),或者使用反引号 不,我需要对它进行 htmlspecialchars 编码。没有文字引号,所以我不能反引号。 反引号有什么问题? uploadVariantPicture(`size:"test2"`) 在语法上是有效的。如果您需要 uploadVariantPicture 使用编码字符串,那么我强烈建议让 uploadVariantPicture 执行该转换,而不是让每个调用者单独执行。 @TonyFriz 您需要获取有效的 JS 代码(无论您选择哪个),然后 (仅)在将其放入 HTML href 属性时 您必须实体-转义文本。这意味着(所有!)" 字符变为&amp;quot; 并且(所有)' 字符变为&amp;apos;。但说真的,正如这个答案所建议的那样,首先不要将 JS 代码放在 HTML 属性中。

以上是关于尽管使用 htmlspecialchars 对单引号进行编码,JavaScript 仍然抱怨这些引号需要在函数调用中转义的主要内容,如果未能解决你的问题,请参考以下文章

发送电子邮件时 Laravel htmlspecialchars() 错误

2shell中处理字符串

htmlspecialchars() 或 如何以及在何处使用?

在插入 MySQL 之前使用 htmlspecialchars() 好吗?

htmlspecialchars() - 如何以及何时使用和避免多次使用

htmlspecialchars() 应该用于输入信息还是输出之前?