【问题标题】:Parse contents of script tags inside string解析字符串内脚本标签的内容
【发布时间】:2015-07-14 00:43:40
【问题描述】:

假设我有以下字符串:

var myString = "<p>hello</p><script>console.log('hello')</script><h1>Test</h1><script>console.log('world')</script>"

我想使用 split 来获取一个包含脚本标签内容的数组。例如我希望我的输出是:

["console.log('hello')", "console.log('world')"]

我尝试做myString.split(/[&lt;script&gt;&lt;/script&gt;]/) 但没有得到预期的输出。

感谢任何帮助。

【问题讨论】:

标签: javascript regex


【解决方案1】:

You can't parse (X)HTML with regex.

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

var element = document.createElement('div');
element.innerHTML = myString; // Parse HTML properly (but unsafely)

但是,这并不安全。即使innerHTML 没有在script 元素中运行JS,恶意字符串仍然可以运行任意JS,例如&lt;img src="//" onerror="alert()"&gt;

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

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

或者,新的浏览器支持DOMParser

var doc = new DOMParser().parseFromString(myString, 'text/html');

将 HTML 字符串解析为 DOM 后,您可以使用 DOM 方法,如 getElementsByTagNamequerySelectorAll 来获取所有 script 元素。

var scriptElements = doc.getElementsByTagName('script');

最后,[].map 可用于获得一个数组,其中包含每个 script 元素的 textContent

var arrayScriptContents = [].map.call(scriptElements, function(el) {
    return el.textContent;
});

完整的代码是

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

【讨论】:

  • 片段还不够吗?某些浏览器会在添加时执行脚本吗? PS:地图最终会出现在什么 var 中?
  • 我喜欢看到那个史诗般的链接。
  • @mplungjan JS 中的 script 元素在使用 innerHTML 创建时永远不会运行。但是,其他 JS 代码可能会运行,例如&lt;img src="//" onerror="alert()"&gt;。因此,我使用了“sandbox”。
  • 那么字符串在哪里呢?您映射并有一个数组 [] 但保存它们的 var 在哪里?
  • @mplungjan 对[].map 的调用返回所需的数组。它可以分配给某个变量:var arr = [].map.call(/* ... */).
【解决方案2】:

Javascript 代码:

   function myFunction() {
        var str = "<p>hello</p><script>console.log('hello')</script><h1>Test</h1><script>console.log('world')</script>";

        console.log(str.match(/<script\b[^>]*>(.*?)<\/script>/gm));
}

【讨论】:

    【解决方案3】:

    你必须像这样转义正斜杠:/。

     myString.split(/(<script>|<\/script>)/)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 2018-02-12
      • 2018-05-18
      • 2015-01-26
      • 2014-09-09
      相关资源
      最近更新 更多