尽管使用 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:'test2'');">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=""">
<element attribute='''>
在源代码中会分别产生"
(双引号)和'
(单引号)的属性值,尽管它们是用于在HTML源代码中引用属性值的分隔符。
因此
<a href="javascript:uploadVariantPicture('size:'test2'');">Link</a>
会产生一个href
的属性值
javascript:uploadVariantPicture('size:'test'');
在 HTML 解析器删除外部双引号之后。
选项可以包括在href
值内适当地转义双引号(HTML &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'");
);
<a>Link</a>
我想不出任何情况下内联处理程序比addEventListener
更可取,除非您故意尝试利用 XSS 漏洞。
【讨论】:
如果我在调用中编码了双引号,这仍然有效吗? 当然,只要uploadVariantPicture('size:"test2"')
,或者使用反引号
不,我需要对它进行 htmlspecialchars 编码。没有文字引号,所以我不能反引号。
反引号有什么问题? uploadVariantPicture(`size:"test2"`)
在语法上是有效的。如果您需要 uploadVariantPicture
使用编码字符串,那么我强烈建议让 uploadVariantPicture
执行该转换,而不是让每个调用者单独执行。
@TonyFriz 您需要获取有效的 JS 代码(无论您选择哪个),然后 (仅)在将其放入 HTML href
属性时 您必须实体-转义文本。这意味着(所有!)"
字符变为&quot;
并且(所有)'
字符变为&apos;
。但说真的,正如这个答案所建议的那样,首先不要将 JS 代码放在 HTML 属性中。以上是关于尽管使用 htmlspecialchars 对单引号进行编码,JavaScript 仍然抱怨这些引号需要在函数调用中转义的主要内容,如果未能解决你的问题,请参考以下文章
发送电子邮件时 Laravel htmlspecialchars() 错误
htmlspecialchars() 或 如何以及在何处使用?
在插入 MySQL 之前使用 htmlspecialchars() 好吗?