javascript 将 html 附加到 jQuery 元素而不在 html 中运行脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5550633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 17:36:01  来源:igfitidea点击:

Append html to jQuery element without running scripts inside the html

javascriptjquerydom

提问by Peter Jaric

I have written some code that takes a string of html and cleans away any ugly HTML from it using jQuery (see an early prototype in this SO question). It works pretty well, but I stumbled on an issue:

我已经编写了一些代码,它使用一串 html 并使用 jQuery 清除其中的任何丑陋的 HTML(请参阅此 SO 问题中的早期原型)。它工作得很好,但我偶然发现了一个问题:

When using .append() to wrap the html in a div, all script elements in the code are evaluated and run (see this SO answerfor an explanation why this happens). I don't want this, I really just want them to be removed, but I can handle that later myself as long as they are not run.

当使用 .append() 将 html 包装在 div 中时,代码中的所有脚本元素都会被评估并运行(请参阅此 SO 答案以了解发生这种情况的原因)。我不想要这个,我真的只想删除它们,但只要它们不运行,我以后可以自己处理。

I am using this code:

我正在使用此代码:

var wrapper = $('<div/>').append($(html));

I tried to do it this way instead:

我试着这样做:

var wrapper = $('<div>' + html + '</div>');

But that just brings forth the "Access denied" error in IE that the append() function fixes (see the answer I referenced above).

但这只会在 IE 中引发 append() 函数修复的“拒绝访问”错误(请参阅我上面引用的答案)。

I think I might be able to rewrite my code to not require a wrapper around the html, but I am not sure, and I'd like to know if it is possible to append html without running scripts in it, anyway.

我想我可能能够重写我的代码而不需要在 html 周围进行包装,但我不确定,我想知道是否可以在不运行脚本的情况下附加 html,无论如何。

My questions:

我的问题:

  • How do I wrap a piece of unknown html without running scripts inside it, preferably removing them altogether?

  • Should I throw jQuery out the window and do this with plain JavaScript and DOM manipulation instead? Would that help?

  • 如何在不运行脚本的情况下包装一段未知的 html,最好将它们完全删除?

  • 我应该将 jQuery 扔出窗口并使用纯 JavaScript 和 DOM 操作来代替吗?那会有帮助吗?

What I am not trying to do:

我不想做的事情:

I am not trying to put some kind of security layer on the client side. I am very much aware that it would be pointless.

我并不是要在客户端设置某种安全层。我非常清楚这将毫无意义。

Update: James' suggestion

更新:詹姆斯的建议

James suggested that I should filter out the script elements, but look at these two examples (the original first and the James' suggestion):

James 建议我应该过滤掉 script 元素,但是看看这两个例子(最初的第一个和 James 的建议):

jQuery("<p/>").append("<br/>hello<script type='text/javascript'>console.log('gnu!'); </script>there")

keeps the text nodes but writes gnu!

保留文本节点但写入 gnu!

jQuery("<p/>").append(jQuery("<br/>hello<script type='text/javascript'>console.log('gnu!'); </script>there").not('script'))`

Doesn't write gnu!, but also loses the text nodes.

不写 gnu!,但也会丢失文本节点。

Update 2:

更新 2:

James has updated his answer and I have accepted it. See my latest comment to his answer, though.

詹姆斯更新了他的答案,我已经接受了。不过,请参阅我对他的回答的最新评论。

采纳答案by James An

How about removing the scripts first?

先删除脚本怎么样?

var wrapper = $('<div/>').append($(html).not('script'));
var wrapper = $('<div/>').append($(html).not('script'));

  • Create the div container
  • Use plain JS to put html into div
  • Remove all script elements in the div
  • 创建 div 容器
  • 使用纯JS将html放入div中
  • 删除 div 中的所有脚本元素

Assuming script elements in the html are not nested in other elements:

假设 html 中的 script 元素没有嵌套在其他元素中:

var wrapper = document.createElement('div');
wrapper.innerHTML = html;
$(wrapper).children().remove('script');
var wrapper = document.createElement('div');
wrapper.innerHTML = html;
$(wrapper).children().remove('script');

var wrapper = document.createElement('div');
wrapper.innerHTML = html;
$(wrapper).find('script').remove();

This works for the case where html is just text and where html has text outside any elements.

这适用于 html 只是文本并且 html 在任何元素之外都有文本的情况。

回答by perpetus

Below is an alternative way to prevent scripts within a loaded html from running:

下面是防止已加载的 html 中的脚本运行的另一种方法:

function preventJS(html) {
     return html.replace(/<script(?=(\s|>))/i, '<script type="text/xml" ');
}

In details it's described here - JavaScript: How to prevent execution of JavaScript within a html being added to the DOM. Probably, this solution will be useful for somebody.

详细描述在这里 - JavaScript:如何防止在 html 中执行 JavaScript 被添加到 DOM。可能这个解决方案对某人有用。

回答by bpierre

You should remove the scriptelements:

您应该删除script元素:

var wrapper = $('<div/>').append($(html).remove("script"));
var wrapper = $('<div/>').append($(html).remove("script"));

Second attempt:

第二次尝试:

node-validator can be used in the browser: https://github.com/chriso/node-validator

node-validator 可以在浏览器中使用:https: //github.com/chriso/node-validator

var str = sanitize(large_input_str).xss();

Alternatively, PHPJS has a strip_tags function (regex/evil based): http://phpjs.org/functions/strip_tags:535

可替代地,PHPJS具有用strip_tags函数(正则表达式/恶为基础): http://phpjs.org/functions/strip_tags:535