浏览器的四大线程
1.GUI渲染线程
2.javascript引擎线程
3.浏览器事件触发线程
4.HTTP请求线程
通常线程之间的交互以事件的方式发生,通过事件回调的方法予以通知。事件回调,是以先进先出的方式添加到任务队列的末尾,等js引擎空闲时,任务队列中排队的任务将会依次被执行。这些事件回调包括setTimeout, setInterval,click, ajax异步请求回调。
浏览器中,js引擎线程会循环从任务队列中读取事件并且执行,这种运行机制称作 Event Loop(事件循环)。
当ajax请求被服务器响应并且受到response后,浏览器事件触发线程捕获了ajax的回调事件 onreadystatechange(当然也可能触发onload,或者onerror等等)。该事件没有立即被执行,而是添加到任务队列的末尾。等js引擎空闲了,任务队列的任务才会被捞出来,然后挨个执行。
在onreadystatechange事件回调内部,有可能对dom进行操作。此时浏览器会挂起js引擎线程,转而执行GUI渲染线程,进行UI重绘(repaint)或者回流(reflow).当js引擎重新执行时,GUI渲染线程又会被挂起,GUI更新会被保存起来,等到js引擎空闲时立即被执行。
XMLHttpRequest 属性解读
XMLHttpRequest的实例对象没有自有属性。实际上,他的所有属性均来自XMLHttpRequest.prototype
XMLHttpRequest实例对象具有如下的继承关系
xhr << XMLHttpRequest.prototype << XMLHttpRequestEventTarget.prototype << EventTarget.prototype << Object.prototype
readyState属性
只读。
onreadystatechange
onreadystatechange事件回调方法在readystate状态改变时触发,在一个收到响应的ajax请求周期中,onreadystatechange方法会被触发4次,因此可以在onreadystatechange方法中绑定一些事件回调。
xhr.onreadystatechange = function(e){
if(xhr.readystate==4){
var s = xhr.status;
if((s >= 200 && s < 300) || s == 304){
var resp = xhr.responseText;
//TODO ...
}
}
}
注意: onreadystatechange回调中默认会传入Event实例
status
只读属性。status表示http请求的状态。初始值为0,如果服务器没有显式地指定状态码, 那么status将被设置为默认值, 即200.
statusText
只读属性, statusText表示服务器的响应状态信息, 它是一个 UTF-16 的字符串, 请求成功且status==20X时, 返回大写的 OK . 请求失败时返回空字符串. 其他情况下返回相应的状态描述. 比如: 301的 Moved Permanently , 302的 Found , 303的 See Other , 307 的 Temporary Redirect , 400的 Bad Request , 401的 Unauthorized 等等.
onloadstart
onloadstart事件回调方法在ajax请求发送之前触发, 触发时机在 readyState==1 状态之后, readyState==2 状态之前.
onloadstart方法中默认将传入一个ProgressEvent事件进度对象. 如下:
ProgressEvent对象具有三个重要的Read only属性
lengthComputable 表示长度是否可计算, 它是一个布尔值, 初始值为false.
loaded 表示已加载资源的大小, 如果使用http下载资源, 它仅仅表示已下载内容的大小, 而不包括http headers等. 它是一个无符号长整型, 初始值为0.
total 表示资源总大小, 如果使用http下载资源, 它仅仅表示内容的总大小, 而不包括http headers等, 它同样是一个无符号长整型, 初始值为0.
onprogress
onprogress事件回调方法在 readyState==3 状态时开始触发, 默认传入 ProgressEvent 对象, 可通过 e.loaded/e.total 来计算加载资源的进度, 该方法用于获取资源的下载进度.
onload
onload事件回调方法在ajax请求成功后触发, 触发时机在 readyState==4 状态之后.
想要捕捉到一个ajax异步请求的成功状态, 并且执行回调, 一般下面的语句就足够了:
xhr.onload = function(){
var s = xhr.status;
if((s >= 200 && s < 300) || s == 304){
var resp = xhr.responseText;
//TODO ...
}
}
onloadend
onloadend事件回调方法在ajax请求完成后触发, 触发时机在 readyState==4 状态之后(收到响应时) 或者 readyState==2 状态之后(未收到响应时).
onloadend方法中默认将传入一个ProgressEvent事件进度对象.
timeout
timeout属性用于指定ajax的超时时长. 通过它可以灵活地控制ajax请求时间的上限. timeout的值满足如下规则:
通常设置为0时不生效
设置为字符串时, 如果字符串中全部为数字, 它会自动将字符串转化为数字, 反之该设置不生效.
设置为对象时, 如果该对象能够转化为数字, 那么将设置为转化后的数字.
ontimeout
ontimeout方法在ajax请求超时时触发, 通过它可以在ajax请求超时时做一些后续处理.
response responseText
均为只读属性, response表示服务器的响应内容, 相应的, responseText表示服务器响应内容的文本形式.
responseXML
只读属性, responseXML表示xml形式的响应数据, 缺省为null, 若数据不是有效的xml, 则会报错.
responseType
responseType表示响应的类型, 缺省为空字符串, 可取 "arraybuffer" , "blob" , "document" , "json" , and "text" 共五种类型.
responseURL
responseURL返回ajax请求最终的URL, 如果请求中存在重定向, 那么responseURL表示重定向之后的URL.
withCredentials
withCredentials是一个布尔值, 默认为false, 表示跨域请求中不发送cookies等信息. 当它设置为true时, cookies , authorization headers 或者 TLS客户端证书 都可以正常发送和接收. 显然它的值对同域请求没有影响.
注意: 该属性适用于 IE10+, opera12+及其他现代浏览器.
abort
abort方法用于取消ajax请求, 取消后, readyState 状态将被设置为 0 (UNSENT). 如下, 调用abort 方法后, 请求将被取消.
getResponseHeader
getResponseHeader方法用于获取ajax响应头中指定name的值. 如果response headers中存在相同的name, 那么它们的值将自动以字符串的形式连接在一起.
console.log(xhr.getResponseHeader('Content-Type'));//"text/html"
getAllResponseHeaders
getAllResponseHeaders方法用于获取所有安全的ajax响应头, 响应头以字符串形式返回. 每个HTTP报头名称和值用冒号分隔, 如key:value, 并以rn结束.
xhr.onreadystatechange = function() {
if(this.readyState == this.HEADERS_RECEIVED) {
console.log(this.getAllResponseHeaders());
}
}
//Content-Type: text/html"
setRequestHeader
既然可以获取响应头, 那么自然也可以设置请求头, setRequestHeader就是干这个的. 如下:
//指定请求的type为json格式
xhr.setRequestHeader("Content-type", "application/json");
//除此之外, 还可以设置其他的请求头
xhr.setRequestHeader('x-requested-with', '123456');
onerror
onerror方法用于在ajax请求出错后执行. 通常只在网络出现问题时或者ERR_CONNECTION_RESET时触发(如果请求返回的是407状态码, chrome下也会触发onerror).
upload
upload属性默认返回一个 XMLHttpRequestUpload 对象, 用于上传资源. 该对象具有如下方法:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。