簡體   English   中英

如何從字符串加載腳本標簽?

[英]How can I load script tags from a string?

外部來源正在提供以字符串形式編寫為 HTML 的腳本標簽的內容。 我需要將這些腳本標簽添加到頭部。 如果我這樣做,所有腳本標簽都會添加到 head 標簽中的 DOM 中,但是實際上並沒有加載任何源(devtools 網絡選項卡)。

<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  </head>
  <body>
    <script>
        let sLoadThis = '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/underscore@latest/underscore-umd-min.js">'
        sLoadThis = sLoadThis + "<" + "/script>"
        let oScript = $(sLoadThis).get(0);
        document.head.appendChild(oScript);
    </script>
  </body>
</html>

如果我使用 jQuery 作為解釋器,然后用 vanilla JS 插入腳本標簽,它可以工作:


<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  </head>
  <body>
    <script>
        let sLoadThis = '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/underscore@latest/underscore-umd-min.js">'
        sLoadThis = sLoadThis + "<" + "/script>"
        let oScript = $(sLoadThis).get(0);
        var vanillaScript = document.createElement('script')
        vanillaScript .type = 'text/javascript'
        vanillaScript .src = oScript.src
        document.head.appendChild(vanillaScript )
    </script>
  </body>
</html>

我想了解為什么它在我的第一個示例中不起作用。

據我所知,有 4 種方法可以從字符串創建 DOM 元素:

  • 選項 1:innerHTML
  • 選項 2:插入相鄰 HTML
  • 選項 3:DOMParser().parseFromString
  • 選項 4:createRange().createContextualFragment

HTML5 指定使用前三個選項之一插入的<script>標記不應執行,因為它可能會成為安全風險。 看到這個

因此,在示例中,雖然所有腳本標簽都添加到<head>部分的 DOM 中,但只會執行選項編號 4。

 const str1 = "<script>alert('option 1 executed')" + "<" + "/script>" const str2 = "<script>alert('option 2 executed')" + "<" + "/script>" const str3 = "<script>alert('option 3 executed')" + "<" + "/script>" const str4 = "<script>alert('option 4 executed')" + "<" + "/script>" // OPTION 1 const placeholder1 = document.createElement('div') placeholder1.innerHTML = str1 const node1 = placeholder1.firstChild document.head.appendChild(node1) // OPTION 2 const placeholder2 = document.createElement('div') placeholder2.insertAdjacentHTML('afterbegin', str2) const node2 = placeholder2.firstChild document.head.appendChild(node2) // OPTION 3 const node3 = new DOMParser().parseFromString(str3, 'text/html').head.firstElementChild document.head.appendChild(node3) // OPTION 4 const node4 = document.createRange().createContextualFragment(str4) document.head.appendChild(node4)

第二個示例運行是因為您使用的是 dom 節點。 這就是appendChild()的工作原理。 jQuery get()方法適用於現有的 dom 元素。 你唯一擁有的是一個字符串,它還不存在於你的 dom 中。 試試下面的。

let script = $.parseHtml(sLoadThis);
console.log(script.get(0)); // should be a script dom node element

document.head.appendChild(script.get(0));

在原版JavaScript中,它比 jQuery 更容易、更快,因為您不必使用依賴項。

const fragment = document.createRange().createContextualFragment(htmlStr);
document.head.appendChild(fragment);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM