Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么没有';脚本不能执行吗?_Javascript_Html_Ajax_Single Page Application - Fatal编程技术网

Javascript 为什么没有';脚本不能执行吗?

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

我正在尝试制作一个web应用程序,使用AJAX刷新其内容、样式和脚本,这样网站就可以在不重新加载页面的情况下更新所有内容

因此,首先我获取页面,当页面加载时,我使用ajax向服务器发出请求并获取html内容,然后另一个请求获取样式,最后另一个请求获取脚本并将其放入脚本标记中

<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可能是一个解决方案,但我希望有一个更好的解决方案,因为不鼓励使用eval

HTML规范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)