说明
浏览器工作原理与实践专栏学习笔记
回调函数
什么是回调函数呢(Callback Function)?
将一个函数作为参数传递给另外一个函数,那作为参数的这个函数就是回调函数。
同步回调
回调函数 callback 是在主函数返回之前执行的,这个回调过程称为同步回调。
例子:
let callback = function(){ console.log('i am do homework') } function doWork(cb) { console.log('start do work') cb() console.log('end do work') } doWork(callback)
异步回调
把回调函数在主函数外部执行的过程称为异步回调。
一般有两种方式:
- 第一种是把异步函数做成一个任务,添加到信息队列尾部;
- 第二种是把异步函数添加到微任务队列中,这样就可以在当前任务的末尾处执行微任务了。
例子:
let callback = function(){ console.log('i am do homework') } function doWork(cb) { console.log('start do work') setTimeout(cb,1000) console.log('end do work') } doWork(callback)
系统调用栈
当循环系统在执行一个任务的时候,都要为这个任务维护一个系统调用栈。这个系统调用栈类似于 JavaScript 的调用栈,只不过系统调用栈是 Chromium 的开发语言 C++ 来维护的。
跟踪事件分析工具 chrome://tracing/
(浏览器打开):用来抓取完整的调用栈信息。
也可以通过 Performance 来抓取它核心的调用信息,如下图所示:
这是一个 Parse HTML 的任务执行过程:
- 黄色的条目表示执行 JavaScript 的过程
- 其他颜色的条目表示浏览器内部系统的执行过程。
XMLHttpRequest 运作机制
工作流程图
- 渲染进程会将请求发送给网络进程
- 然后网络进程负责资源的下载
- 等网络进程接收到数据之后,就会利用 IPC 来通知渲染进程
- 渲染进程接收到消息之后,会将 xhr 的回调函数封装成任务并添加到消息队列中
- 等主线程循环系统执行到该任务的时候,就会根据相关的状态来调用对应的回调函数。
用法
function GetWebData(URL){ /** * 1:新建XMLHttpRequest请求对象 */ let xhr = new XMLHttpRequest() /** * 2:注册相关事件回调处理函数 */ xhr.onreadystatechange = function () { switch(xhr.readyState){ case 0: //请求未初始化 console.log("请求未初始化") break; case 1://OPENED console.log("OPENED") break; case 2://HEADERS_RECEIVED console.log("HEADERS_RECEIVED") break; case 3://LOADING console.log("LOADING") break; case 4://DONE if(this.status == 200||this.status == 304){ console.log(this.responseText); } console.log("DONE") break; } } xhr.ontimeout = function(e) { console.log('ontimeout') } xhr.onerror = function(e) { console.log('onerror') } /** * 3:打开请求 */ xhr.open('Get', URL, true);//创建一个Get请求,采用异步 /** * 4:配置参数 */ xhr.timeout = 3000 //设置xhr请求的超时时间 xhr.responseType = "text" //设置响应返回的数据格式 xhr.setRequestHeader("X_TEST","time.geekbang") /** * 5:发送请求 */ xhr.send(); }
执行过程
第一步:创建 XMLHttpRequest 对象。
用来执行实际的网络请求操作。
第二步:为 xhr 对象注册回调函数。
XMLHttpRequest 的回调函数主要有下面几种:
ontimeout,用来监控超时请求,如果后台请求超时了,该函数会被调用;
onerror,用来监控出错信息,如果后台请求出错了,该函数会被调用;
onreadystatechange,用来监控后台请求过程中的状态,比如可以监控到 HTTP 头加载完成的消息、HTTP 响应体消息以及数据加载完成的消息等。
第三步:配置基础的请求信息
注意:open 方法仅仅是配置数据,没有任何真实的连接产生,所有连接阶段都是在 send 之后
通过 open 接口配置一些基础的请求信息,包括请求的地址、请求方法(是 get 还是 post)和请求方式(同步还是异步请求)。
通过 xhr 内部属性类配置一些其他可选的请求信息,比如:xhr.timeout = 3000 来配置超时时间
通过 xhr.responseType = "text" 来配置服务器返回的格式
通过 xhr.setRequestHeader 来添加自己专用的请求头属性
服务器返回类型的描述:
第四步:发起请求。
调用xhr.send来发起网络请求
参考资料
XMLHttpRequest 使用过程中的“坑”
跨域问题
在 A 站点中去访问不同源的 B 站点的内容,默认情况下,跨域请求是不被允许的。
HTTPS 混合内容的问题
HTTPS 混合内容是 HTTPS 页面中包含了不符合 HTTPS 安全要求的内容。
比如包含了 HTTP 资源,通过 HTTP 加载的图像、视频、样式表、脚本等,都属于混合内容。
HTTPS 混合内容警告:
测试:通过浏览器打开地址 https://www.iteye.com/groups ,然后通过控制台,使用 XMLHttpRequest 来请求 http://img-ads.csdn.net/2018/201811150919211586.jpg ,这时候请求就会报错
VM115:52 Mixed Content: The page at ‘https://www.iteye.com/groups’ was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ‘http://img-ads.csdn.net/2018/201811150919211586.jpg’. This request has been blocked; the content must be served over HTTPS.