[英]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.