我有一个像 "CS5990+-&|!(){}[]^"~*?:\" 这样的字符串
我想将此字符串用作表达式中的选择器,例如
$('[data-name="' + string + '"]')
其中 string 是上面的字符串。但是由于最后一个斜杠,jquery 的嘶嘶声会引发错误。无论如何我可以转义这个字符串并仍然使用这个字符串作为选择器吗?我尝试了 escape(),但它抛出了一个错误。请帮忙
我有一个像 "CS5990+-&|!(){}[]^"~*?:\" 这样的字符串
我想将此字符串用作表达式中的选择器,例如
$('[data-name="' + string + '"]')
其中 string 是上面的字符串。但是由于最后一个斜杠,jquery 的嘶嘶声会引发错误。无论如何我可以转义这个字符串并仍然使用这个字符串作为选择器吗?我尝试了 escape(),但它抛出了一个错误。请帮忙
要使用任何元字符(例如 !"#$%&'()*+,./:;<=>?@[]^`{|}~ )作为名称的文字部分,它必须用两个反斜杠转义:\\. - http://api.jquery.com/category/selectors/
对于选择器中的属性值,您似乎只需双重转义反斜杠和引号即可逃脱,例如
var string = "CS5990+-&|!(){}[]^\\\"\~*?:\\\\";
这是一个在选择器中转义特殊字符的函数:
function escapeSelector(selector) {
selector = selector.replace(/\\/g,'\\\\');
return selector.replace(/([ #;&,.+*~\':"@!^$[\]()<=>|\/\{\}\?])/g,'\\$1');
}
给定的代码片段有问题:
$('[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 片段:
document.querySelector("#foo-bar-baz")
…ID(或选择器中出现的任何其他内容)本质上是用户提供的输入——它由网页提供!
你猜怎么着?旧的实现出现转义错误,在某些情况下会产生无效的 JavaScript 代码,在其他情况下会产生无效的 UTF-8。
修复(和简化)代码的补丁遵循我上面描述的逻辑。
用 '\' 转义你的 '\' 和 '"'
string = 'CS5990+-&|!(){}[]^\"~*?:\\'
试试这个:
var string = 'CS5990\\+\\-\\&\\|\\!\\(\\)\\{\\}\\[\\]\\^\\"\\~\\*\\?\\:\\\\';
alert($('#'+string).val());