安全性关注从html中删除标签的方法(Security concern over method of removing tags from html)

我正在使用findAndReplaceDOMText ,这是一个允许您包装跨多个标签的文本的库。

考虑在以下html中的<em>标记中包装ob :

<p>foo <span>bar</span></p>

附加信息:

我正在使用findAndReplaceDOMText选项preset: "prose" :

忽略非文本元素(例如<script> , <svg> , <optgroup>, `等)

$(this).replaceWith($(this).html()) ,更简单的$(this).replaceWith($(this).html())导致文本节点数量激增。 通过上面的例子,我们得出: <p>"fo""o "<span>"b""ar"</span></p> (其中文本节点用"表示。)如果你这会导致问题尝试重新应用findAndReplaceDOMText除了一般臭。

插入的span元素有一个.deepSearch-highlight类(与上面的示例形成对比,后者将文本包装在em 。请参阅下面的完整代码。

import $ from "jquery" import findAndReplaceDomText from "findandreplacedomtext" import buildRegex from "../../shared/buildRegex" import scrollToElement from "./scrollToElement" export default function search(queryParams) { const regex = buildRegex(queryParams) findAndReplaceDomText($('body')[0], { find: regex, replace: createHighlight, preset: "prose", filterElements, }) scrollToElement($(".deepSearch-current-highlight")) } function createHighlight(portion, match) { var wrapped = document.createElement("span") var wrappedClasses = "deepSearch-highlight" if (match.index === 0) { wrappedClasses += " deepSearch-current-highlight" } wrapped.setAttribute("class", wrappedClasses) wrapped.setAttribute("data-highlight-index", match.index) wrapped.appendChild(document.createTextNode(portion.text)) return wrapped } function filterElements(elem) { const $elem = $(elem) return $elem.is(":visible") && !$elem.attr("aria-hidden") }

I am using findAndReplaceDOMText, a library that lets you wrap text that spans multiple tags.

Consider wrapping o b in <em> tags in the following html:

<p>foo <span>bar</span></p>

Additional Information:

I am using the findAndReplaceDOMText option preset: "prose" which:

Ignore non-textual elements (E.g. <script>, <svg>, <optgroup>,`, etc.)

As an aside, the much simpler $(this).replaceWith($(this).html()) results in an explosion in the number of text nodes. With the above example we would result in: <p>"fo""o "<span>"b""ar"</span></p> (where text nodes are denoted with "). That's causes problems if you try reapplying findAndReplaceDOMText in addition to being generally smelly.

The inserted span elements have a class of .deepSearch-highlight (in contrast to the above example which wraps text in em's. See the full code below.

.

import $ from "jquery" import findAndReplaceDomText from "findandreplacedomtext" import buildRegex from "../../shared/buildRegex" import scrollToElement from "./scrollToElement" export default function search(queryParams) { const regex = buildRegex(queryParams) findAndReplaceDomText($('body')[0], { find: regex, replace: createHighlight, preset: "prose", filterElements, }) scrollToElement($(".deepSearch-current-highlight")) } function createHighlight(portion, match) { var wrapped = document.createElement("span") var wrappedClasses = "deepSearch-highlight" if (match.index === 0) { wrappedClasses += " deepSearch-current-highlight" } wrapped.setAttribute("class", wrappedClasses) wrapped.setAttribute("data-highlight-index", match.index) wrapped.appendChild(document.createTextNode(portion.text)) return wrapped } function filterElements(elem) { const $elem = $(elem) return $elem.is(":visible") && !$elem.attr("aria-hidden") }

最满意答案

如果您只想删除元素并保留其文本子项,请不要处理HTML。 您应该使用移动文本和元素节点的纯DOM API。 使用HTML解析器最多会产生次优性能,并在最坏的情况下产生安全漏洞。

顺便说一句,更简单的$(this).replaceWith($(this).html())会导致文本节点数量激增。

这可以通过将Node.normalize()应用于祖先来解决。

Do not process HTML if you only want to remove elements and retain their text children. You should use plain DOM APIs that move text and element nodes. Using the HTML parser gives suboptimal performance at best and creates security holes at worst.

As an aside, the much simpler $(this).replaceWith($(this).html()) results in an explosion in the number of text nodes.

This can be solved by applying Node.normalize() to an ancestor.

安全性关注从html中删除标签的方法(Security concern over method of removing tags from html)

我正在使用findAndReplaceDOMText ,这是一个允许您包装跨多个标签的文本的库。

考虑在以下html中的<em>标记中包装ob :

<p>foo <span>bar</span></p>

附加信息:

我正在使用findAndReplaceDOMText选项preset: "prose" :

忽略非文本元素(例如<script> , <svg> , <optgroup>, `等)

$(this).replaceWith($(this).html()) ,更简单的$(this).replaceWith($(this).html())导致文本节点数量激增。 通过上面的例子,我们得出: <p>"fo""o "<span>"b""ar"</span></p> (其中文本节点用"表示。)如果你这会导致问题尝试重新应用findAndReplaceDOMText除了一般臭。

插入的span元素有一个.deepSearch-highlight类(与上面的示例形成对比,后者将文本包装在em 。请参阅下面的完整代码。

import $ from "jquery" import findAndReplaceDomText from "findandreplacedomtext" import buildRegex from "../../shared/buildRegex" import scrollToElement from "./scrollToElement" export default function search(queryParams) { const regex = buildRegex(queryParams) findAndReplaceDomText($('body')[0], { find: regex, replace: createHighlight, preset: "prose", filterElements, }) scrollToElement($(".deepSearch-current-highlight")) } function createHighlight(portion, match) { var wrapped = document.createElement("span") var wrappedClasses = "deepSearch-highlight" if (match.index === 0) { wrappedClasses += " deepSearch-current-highlight" } wrapped.setAttribute("class", wrappedClasses) wrapped.setAttribute("data-highlight-index", match.index) wrapped.appendChild(document.createTextNode(portion.text)) return wrapped } function filterElements(elem) { const $elem = $(elem) return $elem.is(":visible") && !$elem.attr("aria-hidden") }

I am using findAndReplaceDOMText, a library that lets you wrap text that spans multiple tags.

Consider wrapping o b in <em> tags in the following html:

<p>foo <span>bar</span></p>

Additional Information:

I am using the findAndReplaceDOMText option preset: "prose" which:

Ignore non-textual elements (E.g. <script>, <svg>, <optgroup>,`, etc.)

As an aside, the much simpler $(this).replaceWith($(this).html()) results in an explosion in the number of text nodes. With the above example we would result in: <p>"fo""o "<span>"b""ar"</span></p> (where text nodes are denoted with "). That's causes problems if you try reapplying findAndReplaceDOMText in addition to being generally smelly.

The inserted span elements have a class of .deepSearch-highlight (in contrast to the above example which wraps text in em's. See the full code below.

.

import $ from "jquery" import findAndReplaceDomText from "findandreplacedomtext" import buildRegex from "../../shared/buildRegex" import scrollToElement from "./scrollToElement" export default function search(queryParams) { const regex = buildRegex(queryParams) findAndReplaceDomText($('body')[0], { find: regex, replace: createHighlight, preset: "prose", filterElements, }) scrollToElement($(".deepSearch-current-highlight")) } function createHighlight(portion, match) { var wrapped = document.createElement("span") var wrappedClasses = "deepSearch-highlight" if (match.index === 0) { wrappedClasses += " deepSearch-current-highlight" } wrapped.setAttribute("class", wrappedClasses) wrapped.setAttribute("data-highlight-index", match.index) wrapped.appendChild(document.createTextNode(portion.text)) return wrapped } function filterElements(elem) { const $elem = $(elem) return $elem.is(":visible") && !$elem.attr("aria-hidden") }

最满意答案

如果您只想删除元素并保留其文本子项,请不要处理HTML。 您应该使用移动文本和元素节点的纯DOM API。 使用HTML解析器最多会产生次优性能,并在最坏的情况下产生安全漏洞。

顺便说一句,更简单的$(this).replaceWith($(this).html())会导致文本节点数量激增。

这可以通过将Node.normalize()应用于祖先来解决。

Do not process HTML if you only want to remove elements and retain their text children. You should use plain DOM APIs that move text and element nodes. Using the HTML parser gives suboptimal performance at best and creates security holes at worst.

As an aside, the much simpler $(this).replaceWith($(this).html()) results in an explosion in the number of text nodes.

This can be solved by applying Node.normalize() to an ancestor.