说明
浏览器工作原理与实践专栏学习笔记
回调函数
什么是回调函数呢(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来发起网络请求
参考资料
Chromium 对 XMLHttpRequest 的实现
XMLHttpRequest 使用过程中的“坑”
跨域问题
在 A 站点中去访问不同源的 B 站点的内容,默认情况下,跨域请求是不被允许的。
HTTPS 混合内容的问题
HTTPS 混合内容是 HTTPS 页面中包含了不符合 HTTPS 安全要求的内容。
比如包含了 HTTP 资源,通过 HTTP 加载的图像、视频、样式表、脚本等,都属于混合内容。
HTTPS 混合内容警告:
测试:通过浏览器打开地址 https://www.iteye.com/groups ,然后通过控制台,使用 XMLHttpRequest
来请求 ,这时候请求就会报错
VM115:52 Mixed Content: The page at ‘https://www.iteye.com/groups’ was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ‘javascript:void(0)’. This request has been blocked; the content must be served over HTTPS.