给定的代码sn-p有问题:
$('[data-name="' + string + '"]');
可变部分是string。假设这是用户控制的输入会有所帮助。 (它可能不适用于您的特定用例,但无论如何,您的问题的解决方案都是相同的,并且以这种方式思考它会使不正确解决这个问题的危险更加清晰。)
想象一下如果string 包含" 会发生什么,例如string === 'foo"bar'。这会产生[data-name="foo"bar"],打破属性选择器,可能会破坏整个 CSS 选择器并导致抛出异常。
更糟糕的是,想象一下如果 string 是像 '"], #my-evil-selector, [x="' 这样精心设计的值会发生什么。在这种情况下,我们得到:
[data-name=""], #my-evil-selector, [x=""]
换句话说,选择器现在选择的元素可能与您的预期完全不同。这可能是一个安全问题!
解决方法有两个:
将string 包装在对CSS.escape 的调用中。无论string 持有哪个字符串值,CSS.escape(string) 始终会生成一个有效的 CSS 标识符。
既然我们现在有了一个有效的 CSS 标识符,我们就可以不再在属性值周围加上引号了。 (或者,要保留引号,您必须将 string 转换为有效的 CSS 字符串文字,这似乎更难做到没有任何好处。)
所以最终的解决方案是:
$('[data-name=' + CSS.escape(string) + ']');
有趣的事实: 在 Chrome DevTools 中检查元素时,右键菜单提供了一个“复制 JS 路径”选项,其作用与此非常相似。它产生一个 JavaScript sn-p 的形式:
document.querySelector("#foo-bar-baz")
...ID(或选择器中出现的任何其他内容)本质上是用户提供的输入——它由网页提供!
你猜怎么着? The old implementation got the escaping wrong,在某些情况下会生成无效的 JavaScript 代码,在其他情况下会生成无效的 UTF-8。
The patch that fixed (and simplified) the code 遵循我上面描述的逻辑。