在字符串中解析脚本标记的内容

i_t*_*ope 3 javascript regex

假设我有以下字符串:

var myString = "<p>hello</p><script>console.log('hello')</script><h1>Test</h1><script>console.log('world')</script>"
Run Code Online (Sandbox Code Playgroud)

我想使用split来获取包含脚本标记内容的数组.例如,我希望我的输出为:

["console.log('hello')", "console.log('world')"]
Run Code Online (Sandbox Code Playgroud)

我试过myString.split(/[<script></script>]/)但是没有得到预期的输出.

任何帮助表示赞赏.

Ori*_*iol 7

您无法使用正则表达式解析(X)HTML.

相反,您可以使用解析它innerHTML.

var element = document.createElement('div');
element.innerHTML = myString; // Parse HTML properly (but unsafely)
Run Code Online (Sandbox Code Playgroud)

但是,这不安全.即使innerHTML不运行JS内部script元素,恶意字符串仍然可以运行任意JS,例如<img src="//" onerror="alert()">.

要避免该问题,您可以使用DOMImplementation.createHTMLDocument创建新文档,该文档可用作沙箱.

var doc = document.implementation.createHTMLDocument(); // Sandbox
doc.body.innerHTML = myString; // Parse HTML properly
Run Code Online (Sandbox Code Playgroud)

或者,新浏览器支持DOMParser:

var doc = new DOMParser().parseFromString(myString, 'text/html');
Run Code Online (Sandbox Code Playgroud)

一旦HTML字符串被解析到DOM,你可以使用DOM方法类似getElementsByTagNamequerySelectorAll把所有的script元素.

var scriptElements = doc.getElementsByTagName('script');
Run Code Online (Sandbox Code Playgroud)

最后,[].map可以用来获取textContent每个script元素的数组.

var arrayScriptContents = [].map.call(scriptElements, function(el) {
    return el.textContent;
});
Run Code Online (Sandbox Code Playgroud)

完整的代码将是

var doc = document.implementation.createHTMLDocument(); // Sandbox
doc.body.innerHTML = myString; // Parse HTML properly
[].map.call(doc.getElementsByTagName('script'), function(el) {
    return el.textContent;
});
Run Code Online (Sandbox Code Playgroud)

  • 当我看到史诗般的链接时,我喜欢. (3认同)