Skip to content

Latest commit

 

History

History
114 lines (86 loc) · 3.36 KB

17.XMLHttpRequest是如何实现的.md

File metadata and controls

114 lines (86 loc) · 3.36 KB

WebAPI:XMLHttpRequest是怎么实现的?

同步回调 && 异步回调

  • 回调函数: 一个函数做为参数传递给另外一个函数

  • 同步回调 同步回调就是在当前主函数的上下文中执行回调函数

let callback = function() {
	console.log('i do homework');
}
function doWork(cb) {
	console.log('start do homework');
	cb()
	console.log('finish homework')
}
doWork(callback)
// log three statement

  • 异步回调 回调函数没有在主函数内部调用,而是在延时队列里面取出并执行
let callback = function() {
	console.log('i do homework');
}
function doWork(cb) {
	console.log('start do work')
	setTimeout(cb, 1000)
	console.log('finish homework')
}
doWork(callback)
  • 浏览器页面是通过事件循环机制来驱动的,每个渲染进程都有一个消息队列,页面主线程按照顺序来执行消息队列中的事件,每个任务在执行过程中都有自己的调用栈

  • 异步回调两种方式

把异步函数当成一个任务,添加到消息队列尾部 把异步函数添加到微任务队列,可以在当前任务末尾处执行微任务

  • XMLHttpRequest 运作机制

  • 渲染主线程 --> 渲染进程 --> IO进程 --> IPC --> 网络进程 --> 向web服务器请求资源 --> IPC --> IO进程 --> 返回的状态封装成任务添加到消息队列(AJAX回调) --> 消息队列处理任务(根据相关状态调用回调函数) --> 事件循环

function GetWebData(URL) {
	// 新建XMLHTTPRequest请求对象

	let xhr = new XMLHttpRequest();
	
	// 注册相关事件回调处理函数

	xhr.onreadystatechange = function() {
		switch(xhr.readystate) {
			case: 0:
				console.log("请求未初始化");
				break;
			case 1: 
				console.log("opened");
				break;
			case 2:
				console.log("HEADERS_RECEIVED");
				break;
			case 3:
				console.log("LOADING");
				break;
			case 4:
				if(this.status === 200 || this.status === 304) {
					console.log(xhr.responseText)
				}
				console.log("DONE");
				break;
		}
	}
	xhr.ontimeout = function(e) { console.log('ontimeout') }
   xhr.onerror = function(e) { console.log('onerror') }

   xhr.open('GET', URL , true) // 最后一个标识是是否采用异步的请求方式形式执行,默认开启

   // 配置参数

   xhr.timeout = 3000 // 设置 xhr 请求的超时时间
   xhr.responseType = "text" // 设置响应返回的数据格式
   xhr.setRequestHeader("X_TEST","time.geekbang")

   // 发送请求
   xhr.send()
}

AJAX 相应报文格式

  • "" 默认text
  • "text" 返回UTF-16字符串文本
  • "json" 返回js对象
  • "document" DOM对象
  • "blob" 返回包含二进制数据的blob对象
  • "arraybuffer" 包含二进制数据的JS ArrayBuffer

使用的坑,安全策略问题

  • 跨域和混合内容的问题

默认跨域请求是不被允许的,需要自己去单独设置请求头

HTTPS 混合内容(HTTP资源,通过HTTP加载的图像,视频,样式,脚本等等)

总结

  • 回调函数和系统调用栈,循环系统分析AJAX怎么工作,遇到的跨域和混合内容请求的问题

  • 对比setTimeout,其实直接将延迟任务放入延迟队列中去,而XMLHttpRequest则是发起请求让其他浏览器进程或线程去执行,再讲执行的结果通过IPC方式通知渲染进程, 然后渲染进程再将对应的信息添加到消息队列里面中去