【发布时间】:2016-04-09 14:14:31
【问题描述】:
我目前正在构建自己的小型 SPA 框架。我只是好奇,有些事情是如何在后台工作的。
假设我想从服务器动态导入一个脚本。
我目前使用的方法是在头部添加一个脚本标记,并将“async”属性设置为 true。像这样。
for (let requiredScript of requiredScripts){
var $head = document.getElementsByTagName('head')[0];
var $script = document.createElement('script');
$script.src = requiredScript;
$script.async = true;
$script.onload = function(){
callback();
}
$head.appendChild($script);
}
这在浏览器中是如何工作的?我读到浏览器会为 head 标签中的每个脚本生成一个新线程,当它们加载时,它们会执行它们。 (我也可以使用 defer 属性,但这并不重要)。
这(如果它按我预期的那样工作),很棒。语法很丑陋,但它有效。有一点缺点:我无法为这些请求显式设置标头。例如,我想为每个对受限资源的请求添加一个 JWT 令牌,但我不能,我必须使用 ajax 调用。但这不是这个问题的一部分。
所以,加载我的资源的第二种方法(还有第三种方法,ES6 导入,但我现在不会使用它)是通过 AJAX 调用加载我的资源。但是从 XMLHttp 请求的性质来看,我得到的只是一个字符串,或者可能是 JSON,而不是脚本,所以我必须调用 eval(),这既慢又不安全。
但是让我们来回答这个问题。 脚本标签中的资源调用到底是什么?它与 xmlhttp 请求(或 ajax 调用)有何不同?在解析 html 文件并评估带有 script 标签的行时,浏览器到底做了什么?我可以将 javascript 文件作为二进制文件导入,并让浏览器执行它吗? (比 eval() 更快更安全的选择)。 我想完全控制和理解我正在做的事情,但我感到很困惑,找不到关于这个话题的正确答案。
每一个解释(甚至是一个有用的链接)都会非常感激。
【问题讨论】:
-
浏览器基本上只是做一个HTTP GET操作然后解析和解释脚本。一旦 Web 组装得到广泛实施,就可以在服务器上进行预解析。
-
如果您想查看这些 HTTP 事务,浏览器“网络”控制台会显示这些事务。
-
“浏览器基本上只是做一个 HTTP GET 操作,然后解析和解释脚本”这正是让我感到困惑的地方。我可以自己做这个吗?我的意思是,我可以告诉浏览器使用这个“HTTP GET”,然后在响应上使用他的默认解析器和解释器吗?这对我来说似乎很愚蠢,我们所拥有的只是一个旧的、弱的 XMLHttp 请求,它使简单的事情变得复杂。
-
你可以发出一个普通的 xhr 来获取脚本,然后
eval()它,尽管在一些关于eval()工作原理的模糊细节方面存在一些细微差别。 -
但是浏览器不会让你向其他域发出 xhr,但是通过
<script>标签处理完成的隐式 GET 从其他域获取脚本内容是完全可以的。
标签: javascript html ajax resources xmlhttprequest