Javascript 为什么没有';脚本不能执行吗?
我正在尝试制作一个web应用程序,使用AJAX刷新其内容、样式和脚本,这样网站就可以在不重新加载页面的情况下更新所有内容 因此,首先我获取页面,当页面加载时,我使用ajax向服务器发出请求并获取html内容,然后另一个请求获取样式,最后另一个请求获取脚本并将其放入脚本标记中Javascript 为什么没有';脚本不能执行吗?,javascript,html,ajax,single-page-application,Javascript,Html,Ajax,Single Page Application,我正在尝试制作一个web应用程序,使用AJAX刷新其内容、样式和脚本,这样网站就可以在不重新加载页面的情况下更新所有内容 因此,首先我获取页面,当页面加载时,我使用ajax向服务器发出请求并获取html内容,然后另一个请求获取样式,最后另一个请求获取脚本并将其放入脚本标记中 <script> //The script goes here </script> //脚本在这里 然后,我将脚本标记放在html内容的末尾,并用内容完全更新正文 <body> T
<script> //The script goes here </script>
//脚本在这里
然后,我将脚本标记放在html内容的末尾,并用内容完全更新正文
<body>
The HTML content goes here
<script> //and here is the script </script>
</body>
HTML内容在这里
//这是剧本
请求成功,内容加载,样式也随之加载。当我使用浏览器检查器工具时,我可以看到脚本加载到脚本标记中,但脚本不会执行
这是问题的概述,您可以在这里看到代码
app.js提供index.html文件,然后index文件获取script.js文件,该文件使用ajax发送两个请求以获取content.html文件和content.js文件,并将link标记的href属性设置为样式文件。然后将content.js文件放入带有新内容的脚本标记中。虽然content.html已加载,样式文件也已加载,脚本已加载到脚本标记中,但脚本不会执行
为什么会发生这种情况?我如何修复它
--更新--
问题可能真的在于使用innerHTML,但为什么它不能真正工作呢
此外,我认为eval可能是一个解决方案,但我希望有一个更好的解决方案,因为不鼓励使用evalHTML规范dis允许在页面加载后使用
innerHTML
解析动态添加为HTML标记的脚本元素(根据《生活标准》中的)
因此,不使用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");
}
}
);
函数加载脚本(url,回调){
var el=document.createElement(“脚本”);
el.type=“text/javascript”;
函数完成(err){
回调(err,err?false:true);
}
el.onerror=饰面;
如果(el.readyState){/这太长了,不能作为评论发布,所以我将作为答案发布
您正确地注意到:
我认为eval可能是一个解决方案,但我想要一个更好的解决方案,因为不鼓励使用eval
事实上,eval在任何语言中都是有问题的,因为它本质上允许运行的程序将字符串视为代码。最大的问题是,这为代码注入打开了大门(用外行的话来说:黑客)。但这个建议更多的是一个理论建议,而不是关于使用什么函数的建议
那么eval
是什么意思呢?
Eval是允许将字符串解释为代码的任何函数或机制。不同的语言具有不同的函数或功能,允许执行Eval
。例如,某些语言允许递归字符串插值。某些语言具有名为interp()的函数
产生子解释器。有些语言实际上有一个名为eval()的函数
Javascript有四种评估机制:
使用eval()
函数
- 传递给
eval()
的任何字符串都被视为代码
设置脚本标记的src
属性
- 假设
src
属性的值是要下载的javascript文件
- 这适用于文本代码(HTML本身中的实际代码)或动态生成的脚本标记(在javascript中创建脚本元素并设置其src属性)
脚本标记的主体
- 脚本标记中的任何文本都被视为代码
- 这只适用于文字代码。正如您所发现的,使用
innerHTML
设置脚本正文是被禁止的(从Netscape 4——第一个使用javascript的浏览器开始)
javascript:
URI协议
:
之后的所有内容都被视为代码
- 这仅在用户单击链接时有效
因此,您要做的是执行eval
。无论您是否使用eval
功能,您仍然要尝试使用innerHTML
执行eval
(尽管它不起作用)
那么,如果所有内容都是eval
,是否有一种安全的方式在页面上运行javascript?
至少对于现代浏览器来说是这样
现代浏览器实现了一个名为的功能。不幸的是,在编写此答案时,Edge不支持此功能。基本上,您可以计算js文件(如sha1)的哈希值,并在脚本标记中声明它,以便浏览器可以确认js文件未被篡改。以下是一个示例:
<script src="https://cdn.example.com/script.js"
integrity="sha384-+/M6kredJcxdsqkczBUjMLvqyHb1K/JThDXWsBVxMEeZHEaMKEOEct339VItX1zB"></script>
你有这么多疑吗?
视情况而定。eval
问题可能对您非常重要。如果是这样,从外部源加载设置了子资源完整性的javascript是执行javascript的唯一安全方法
但并不是每个人都那么偏执。到目前为止,我们在没有此功能的情况下通常都做得很好。以下是一些经验法则,无论您使用脚本标记还是调用eval()
,都可以减少代码的求值:
始终确保只执行静态javascript代码。不要尝试从字符串构造代码
如果必须从字符串构造代码(例如,使用模板语言,如Handlebar或bundler)