正如你可能知道的,script 标签是用来指定在网页上执行哪个 JavaScript 的。Script 标签可以直接包含 JavaScript 代码,或者指向一个 JavaScript 外链 URL
Script 标签按照它们出现的顺序被执行
下面的代码很直观地说明了这一点:
<script>
var x = 3;
</script>
<script>
alert(x);
// Will alert "3";
</script>
使用外链资源时加载次序没有那么直观,但依然是成立的
<script src="//typekit.com/fj3j1j2.js"></script>
<!-- This second script won’t execute until typekit has executed, or timed out -->
<script src="//my.site/script.js"></script>
如果你混合使用外链和内联的 JavaScript,这个规则同样适用。
这意味着如果你的网站有很慢的脚本在页面较前部分被加载,你的网页加载就会被显著拖慢。这也意味着后加载的脚本可以依赖先加载的脚本。
页面元素在它之前的所有脚本都加载完毕之前是不会执行渲染的。这意味着你可以你可以在页面加载之前在网页上做各种疯狂的事情,当然前提是你不在意因此而造成的性能问题。
然而这个规则不适用于你在网页加载完成之后通过 document.appendChild 之类的方法添加 script 标签到 DOM 中。这些标签会根据浏览器请求处理完成的先后执行脚本,不再保证加载顺序。
当一个 script 标签被执行,在它之前的 HTML 元素可以访问(但是在它之后的还不能用)
<html>
<head>
<script>
// document.head is available
// document.body is not!
</script>
</head>
<body>
<script>
// document.head is available
// document.body is available
</script>
</body>
</html>
你可以想象 HTML 解析器一个标签一个标签地访问文档,当它解析到 script 标签时,马上执行其中的 JavaScript。这意味着只有当开始标签出现在当前脚本之前的 DOM 节点才可以在当前 JavaScript 中被访问(通过 querySelectorALl,jQuery 等等)。
一个有用的推论是 document.head 在任何写在网页上的 JavaScript 几乎总是可用。document.body 只有当你将 script 标签写在 body 标签中或者它之后的时候才可用。
async 和 defer
HTML5 添加了两个工具来控制脚本的执行。
async 表示“不用马上执行它”。更具体地它表示:我不介意你在整个网页加载完成之后执行这个脚本,把它放在其他脚本执行之后。这对于统计分析脚本来说非常有用,因为页面上没有其他的代码需要依赖于统计脚本执行。定义一个页面需要的变量或函数在 async 的代码中是不行的,因为你没有方法知道什么时候 async 代码将会被实际执行。
defer 表示“等待页面解析完成之后执行”。它大致等价于将你的脚本绑定到 DOMContentedLoaded 事件,或者使用 jQuery.ready。当这个代码被执行,DOM 中的一切元素都可用。不同于 async,所有加了 defer 的脚本将会按照它们出现在 HTML 页面中的顺序执行,它只是推迟到 HTML 页面解析完毕后开始执行。
crossorigin!
虽然还没有完全被标准化,但是一些浏览器支持 crossorigin 属性。基本的想法是,浏览器会限制对非同源资源的使用(同源资源是指相同的协议、hostname 以及端口,例如: `http://google.com:80)。
这是为了防止你,例如,向你的竞争对手网站发请求,注销你的用户在对方网站的账号(这不好!)。这个问题牵扯到 script 标签虽然有点意外,但如果实现了 crossorigin,你只要加一个 handler 到 window.onerror 事件上,就能在看控制台上看到一些警告信息,提示你引入了一个不该引入的外站脚本。在安全的浏览器下,除非你指定 crossorigin 属性,不然加载外站脚本不会出错。
crossorgin 不是一个神奇的安全手段,它所做的只是让浏览器启用正常的 CORS 访问检查,发起一个 OPTIONS 请求并检查 Access-Control header。
还有很多不常用的 我就删减了 记录篇文章的目的是由于 在项目中遇到了 script标签拉取时跨域的问题 发现是在头信息中有两个Access-Control-Allow-Origin:* 导致。 后发现在后台nginx 中有配置 所以将标签中的 属性去掉后恢复正常,对于我这个菜鸟来说根本不知道是因为crossorigin这个属性导致 所以找了下资料 记录一下
有兴趣了解全文的 可以
在这里查看: