浏览器的四大线程
1.GUI渲染线程
2.javascript引擎线程
3.浏览器事件触发线程
4.HTTP请求线程
通常线程之间的交互以事件的方式发生,通过事件回调的方法予以通知。事件回调,是以先进先出的方式添加到@H_403_8@任务队列的末尾,等js引擎空闲时,@H_403_8@任务队列中排队的任务将会依次被执行。这些事件回调包括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 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 对象,用于上传资源. 该对象具有如下方法: