[英]Why didn't the script execute?
我正在嘗試制作一個使用AJAX刷新其內容,樣式和腳本的Web應用程序,因此該網站無需重新加載頁面即可更新所有內容。
所以發生的事情是,我首先獲取頁面,並且在加載頁面時,我使用ajax向服務器發出請求並獲取html內容,然后再次請求獲取樣式,最后再次請求獲取腳本並將其放入腳本標簽
<script> //The script goes here </script>
然后,我將script標簽放在html內容的末尾,並用內容完全更新正文
<body>
The HTML content goes here
<script> //and here is the script </script>
</body>
請求成功且內容已加載,因此樣式和樣式以及當我使用瀏覽器檢查器工具時,都可以看到腳本標簽中加載的腳本,但腳本未執行。
這是問題的概述,您可以在這里查看代碼https://codepen.io/Yousef-Essam/project/editor/ZJGxea
app.js提供index.html文件,然后索引文件獲取script.js文件,該文件使用ajax發送兩個請求以獲取content.html文件和content.js文件,並將link標簽的href屬性設置為style文件。 然后將content.js文件放入帶有新內容的腳本標簽中。 盡管加載了content.html和樣式文件,並且腳本已加載到script標記中,但腳本未執行。
為什么會發生這種情況,我該如何解決?
--Update--
問題可能出在使用innerHTML上,但是為什么不真正起作用。
另外,我認為eval可能是一個解決方案,但由於不建議使用eval,因此我希望有一個更好的解決方案
這太長了,無法發布為評論,因此我將其作為答案發布。
您正確地注意到:
我認為eval可能是一個解決方案,但由於不建議使用eval,因此我希望有一個更好的解決方案
實際上,eval在任何語言中都是有問題的,因為它本質上允許正在運行的程序將字符串視為代碼。 這樣做的最大問題是,這為代碼注入打開了大門(用外行的術語:黑客攻擊)。 但是,此建議更多是理論建議,而不是有關使用什么功能的建議。
eval
意味着什么? Eval是任何允許將字符串解釋為代碼的函數或機制。 不同的語言具有不同的功能或特性,可以進行eval
。 例如,某些語言允許遞歸字符串插值。 一些語言具有稱為interp()
的函數,該函數會生成一個子解釋器。 有些語言從字面上講有一個稱為eval()
的函數。
JavaScript具有四種評估機制:
使用eval()
函數。
eval()
任何字符串均視為代碼。 設置腳本標簽的src
屬性
src
屬性的值是要下載的javascript文件 腳本標簽的正文
innerHTML
,禁止使用innerHTML
設置腳本主體(自Netscape 4-第一個使用javascript的瀏覽器以來,此設置已被禁止) javascript:
URI協議
:
之后的所有內容均視為代碼 因此,您想要做的是執行eval
。 無論您是否使用eval
函數都無所謂,您仍在嘗試使用innerHTML
進行eval
(盡管它不起作用)
eval
,是否有一種在頁面上運行javascript的安全方法? 有-至少對於現代瀏覽器而言。
現代瀏覽器實現了一種稱為子資源完整性的功能。 不幸的是,在編寫此答案時,Edge不支持它。 基本上,您可以計算js文件的哈希值(例如sha1),並在script標簽中對其進行聲明,以便瀏覽器可以確認js文件未被篡改。 以下是一個示例:
<script src="https://cdn.example.com/script.js"
integrity="sha384-+/M6kredJcxdsqkczBUjMLvqyHb1K/JThDXWsBVxMEeZHEaMKEOEct339VItX1zB"></script>
這取決於。 eval
問題對您可能真的很重要。 如果是這樣,從設置了子資源完整性的外部源加載javascript 是執行javascript的唯一安全方法 。
但並非每個人都如此偏執。 到目前為止,我們通常在沒有此功能的情況下做得很好。 以下是一些經驗法則,無論您使用script標記還是調用eval()
,它們都可以緩解代碼泄漏:
始終確保您僅執行靜態javascript代碼。 不要嘗試從字符串構造代碼。
如果必須從字符串構造代碼(例如,使用模板語言(如Handlebars)或使用捆綁程序(如Webpack或Browserify)),則切勿在代碼中包含任何用戶生成的內容。 您仍然可以通過發出ajax請求而不是將其包含在代碼中來加載內容。
如果必須在代碼中包含用戶生成的內容,請確保對內容進行清理。 有幾種普遍接受的策略,例如禁止使用特殊字符(如<
和>
和"
或轉義特殊字符。甚至還有庫都可以為您做到這一點)。
基本上,我們要避免的情況是用戶輸入他們的名字為John"; console.log("gotcha");"
以及能夠執行代碼的方式。
HTML規范不允許解析使用innerHTML
在頁面加載后動態添加為HTML標簽的SCRIPT元素(按照生活標准中text屬性描述下的注釋 )。
因此,在不使用eval
來解析腳本的情況下,類似問題的答案在一次簡單的搜索中並不明顯-盡管它們可能存在,但我只看到了場外展示的替代技術。
這是一個不使用eval
的動態加載器。 因為加載腳本是異步的,所以它使用( err, data
)類型的回調函數來指示何時可以調用腳本。
function loadScript( url, callback) {
var el = document.createElement("SCRIPT");
el.type = "text/javascript";
function finish( err) {
callback( err, err ? false : true);
}
el.onerror = finish;
if( el.readyState){ // <= IE 10
el.onreadystatechange = function(){
if( this.readyState == "complete"){
finish( null);
}
};
}
else {
el.onload = function() { finish(null) };
}
el.setAttribute("async", true);
el.src = url;
document.getElementsByTagName("HEAD")[0].appendChild( el);
}
// example call to load jQuery 3.2.1
loadScript( "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js",
function (err, ok) {
if( err) {
console.log( "loading failed: " + err);
}
else {
console.log( "loading success");
}
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.