常用属性

以下是我认为在平时会使用到的一些属性

  1. src
  2. async
  3. defer
  4. type
  5. integrity
  6. crossorigin

script执行过程(async defer)

引入方式

script在HTML有两种添加添加方式

  1. 使用scriptsrc属性将js文件通过链接引入
  2. 将js写在<script></scritp>

两种引入方式的比较

  • 可维护性:外置 Javascript 文件可以被多个页面调用而不用在每个页面上反复地书写.如果有需要改变的部分,你只需要在一处修改即可.所以外置JavaScript 导致代码工作量减少,进而使得维护手续也更加方便。
  • 可缓存:浏览器能够根据具体的设置缓存链接的所有外部 JavaScript文件。也就是说,如果有两个页面都使用同一个文件,那么这个文件只需下载一次。因此,最终结果就是能够加快页面加载的速度。
  • 关注点分离:将 JavaScript 封装在外部的.js文件遵循了关注点分离的法则.总体来说,分离 HTML,CSS 和 JavaScript 从而让我们更容易操纵他们.而且如果是多名开发者同步工作的话,这样也更方便。

加载顺序

要说到script的加载顺序就要先说标签的位置

有defer或者async的情况在后面说

放在head里面

这是传统的做法, 放在这里面会导致所有的JavaScript代码都被 下载 解析 执行 完毕后才会在页面显示内容, 在这段时间页面将一直都是白屏状态, 导致用户的体验非常差.

浏览器在解析到body标签才会解析类容

放在body元素内的最后面

这种在解析JavaScript代码之前, 页面已经完全呈现在浏览器中了, 由于空白页时间变短而感到页面打开的速度加快了.

像js一些对dom的操作强烈建议放在body元素内的最后面, 防止在操作dom节点的时候dom未加载出来,出现报错; 在dom加载完毕之后不会重新回到头部执行script,对dom的操作效果显示不出来.

async 与 defer

async和defer的方式都只对外部脚本是有效的

async

表示应该立即开始下载脚本,但不能阻止其他页面动作,比如下载资源或等待其
他脚本加载, 下载完毕后开始执行. 不会等待

  1. 下载不会阻塞页面解析
  2. 保证会在页面的 load 事件前执行,但可能会在 DOMContentLoaded之后执行
  3. 多个async存在时, 谁先下载完成谁先解析
  4. 在执行时可能有的页面还没有解析完成

由此, 异步脚本不应该在加载期间修改dom

defer

表示脚本可以延迟到文档完全被解析和显示之后再执行

  1. 不会阻塞页面解析
  2. 在html解析完成之后(DOMContentLoaded之前)执行
  3. 按照顺序执行

类型为模块(type="module")的标签

mozilla文档
现代JavaScript教程--什么是模块

在标记了类型为模块之后, 这个标签的内容将被当作JavaScript模块看待

module为异步加载, 不会造成堵塞, 等同与defer属性, 使用相同的执行队列, 谁在前面谁先执行.

具体关于模块的知识点, 在后面专门写一篇来说

integrity 属性

<script integrity="sha256-pojweihxfdkseiwelsfsadknf=" src="xxx"></script>

integrity属性是资源完整性规范的一部分,它允许你为script提供一个hash,用来进行验签,检验加载的JavaScript文件是否完整。

在上面的例子是告诉浏览器使用sha256签名算法对下载的js文件进行计算,并与intergrity提供的摘要签名对比,如果二者不一致,就不会执行这个资源。

作用:

  1. 减少由【托管在CDN的资源被篡改】而引入的XSS 风险
  2. 减少通信过程资源被篡改而引入的XSS风险(同时使用https会更保险)
  3. 可以通过一些技术手段,不执行有脏数据的CDN资源,同时去源站下载对应资源

crossorigin属性

mozilla文档

mozilla关于这个属性的中文文档翻译质量不好, 缩减了一些方便理解的内容, 因此以英文文档为准

crossorigin属性有2个值 anonymous use-credentials

crossorigin="anonymous"

  • 使用CORS
  • credentials flag设置为same-origin 在同源的情况下才会发送cookie等凭据

crossorigin="use-credentials"

  • 使用CORS
  • credentials flag 设置为include 总是会发送cookie等凭据(跨域)

crossorigin="" 或者等于一个错误的值

  • anonymous属性相同

没有crossorigin属性

  • 不会使用CORS
  • 通过 window.onerror 访问错误日志将受到限制。

关于credentials flag 这里关系到CORS的一些详情 我的理解是 在请求的时候类似于:

带credentials的 Fetch :

fetch(url, {
 credentials: 'include'
})

以及带credentials的 XHR :

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);

Credentials必须在前后端都被配置(即the Access-Control-Allow-Credentials header 和 XHR 或Fetch request中都要配置)才能使带credentials的CORS请求成功。


附上跨域相关的文档, 后面可能会用到:

Mozilla crossorigin
Mozilla Access-Control-Allow-Credentials
Request.credentials
预检
最后修改:2022 年 05 月 05 日
如果觉得我的文章对你有用,请随意赞赏