XHR 对象实例所有的配置、属性、方法、回调和不可变值

《XHR 对象实例所有的配置、属性、方法、回调和不可变值》 看到此篇文章的标题,你可能会在想:“我去,怎么又来说XHR这个烂大街的东西!”哈哈,在写这篇深度讲解ajax的文章之前我就预料到肯定会有人这么说了,但是!!!对于一个有理想、有追求、有抱负、有肉的21世纪四有前端程序猿的我来说,我要是再来说怎么创建一个XHR对象,怎么去使用它那你就太小看我了,哈哈,我相信看完此篇文章你或多或少会有一些收获的~

也许没有一个前端程序猿没有使用过ajax,当然也就不可避免的要接触到XHR这个对象(But,虽然我也觉得这种情况不存在,但是为了体现出来鄙人是如此的严谨,哈哈,这里声明一下,如果你是只做IE6及以前版本浏览器的开发者,,你还是先去使用一下XMLHttpRequest再来看此篇文章吧=~=),不过,真正能把XHR对象的一个实例它包含哪些内容都完全说出来的我感觉应该还是少数吧。

当我们声明了一个XMLHttpRequest对象的实例的时候,使用for-in来循环遍历一下这个实例(本文使用的是chrome45版本浏览器),我们会发现在这个实例上绑定了一些内容,我把这些内容进行了一下分类:

一、配置项

也就是对xhr对象进行配置。

① timeout : 配置请求超时时间。

② withCredentials:是否携带发送提供凭据,在下面会进行详细的说明。

二、属性项

也就是指一些请求发送或完成过程中可能会被用户读取或使用到的一些值。

① readyState:xhr的状态码。

② status:http状态码。

③ statusText:http状态说明文本。

④ response:响应。

⑤ responseType:响应类型。

⑥ responseURL:响应的URL路径。

⑦ responseText:响应的文本数据。

⑧ responseXML:响应的XML数据。

⑨ upload:上传对象,在下面会详细说明。

三、方法项

就是可以通过这些方法进行一些交互,如发送请求,获取或设置头部信息等等。

① open:打开一个xhr请求。

② setRequestHeader:设置请求头信息。

③ send:发送请求。

④ abort:中断请求。

⑤ getResponseHeader:获取某一响应头内容。

⑥ getAllResponseHeaders:获取所有响应头内容。

⑦ overrideMimeType:覆盖服务器返回的MIME类型。

xhr对象还有一些例如addEventListener、removeEventListener等等的方法,由于和xhr没太大联系,所以这里就不再写出来了。

四、回调项

回调项的作用是用来当xhr对象发送一些变化的时候来触发某些操作使用的。

① onabort:发生中断事件。

② onerror:产生了错误。

③ ontimeout:请求超时了。

④ onreadystatechange:xhr状态码发生了改变。

⑤ onloadstart:当process开始的时候。(关于procress我们在后面再说)

⑥ onprogress:每次progress正在进行的时候。

⑦ onload:每次progress成功的时候。

⑧ onloadend:当process结束的时候。

五、不可变值

在xhr中存在UNSENT,OPENED,HEADERS_RECEIVED,LOADING,DONE这五个不可变值,他们所代表的内容分别是0,1,2,3,4这五个数字,在open方法调用之前,xhr对象的status属性是UNSENT,也就是0,当调用了open方法之后,但是还没有调用send的时候status的值是OPENED,当调用了send方法,已经接收到响应的头信息时,status就会变为HEADERS_RECEIVED,正在接受响应内容的时候status就是LOADING,请求已完成并且接受完所有响应内容的时候就会变为DONE。

下面对这五个分类的前四个已经里面的内容进行一个详细的记录~(有人可能会问,不是上面分了五个分类吗,可素第五个分类就那5个不可改变的值,也没有什么好说的+_+)

一、配置项

① timeout

timeout是用来设置超时时间的,默认的值是0,也就是说没有超时限制,不管请求多久都不会触发超时。可以给他设置一个类型为数字的值,代表多少毫秒之后如果没有收到响应就触发超时事件(ontimeout)。

② withCredentials

这个值是来配置是否在发送的时候携带着凭据,默认值是false,也就是默认不携带。所谓的凭据指的就是cookie、HTTP认证及客户端SSL证明等信息。这个是在CORS跨域的时候与服务器的Access-Control-Allow-Credentials进行配合使用的,如果发送了携带凭据的请求,但是服务器的响应里面没有Access-Control-Allow-Credentials是true这个值的头,那么浏览器就会由于同源限制把响应给屏蔽掉,并且调用xhr的oerror事件。

例如有下面这一段代码:

javascript(示例代码,没有考虑兼容性)

var  xhr=new  XMLHttpRequest();
xhr.withCredentials=true;
xhr.onreadystatechange=function(){
        if(xhr.readyState==4){
                if(xhr.status==200){
                        console.log("success!");
                }
        }
}
xhr.onerror=function(e){
        console.log("error!");
}
xhr.open("GET","http://127.0.0.1/withCredentials.php");
xhr.send(null);

如果在服务端的代码试下嘛这样子的:

php

header("Access-Control-Allow-Origin:  *");
echo  "ok";

那么肯定会报错,首先因为当客户端的withCredentials设置为true的时候,服务端的Access-Control-Allow-Origin就不能设置为*来代表任意一个域了,需要把请求的域给写出来,如: http://192.168.1.106;另外服务器端需要把Access-Control-Allow-Credentials设置为true,否则会报错:

XMLHttpRequest cannot load http://127.0.0.1/withCredentials.php. Credentials flag is “true”, but the “Access-Control-Allow-Credentials” header is “”. It must be “true” to allow credentials. Origin “http://192.168.1.106” is therefore not allowed access.

所以正确的服务端代码应该是:

php

header("Access-Control-Allow-Origin:  http://192.168.1.106");
header("Access-Control-Allow-Credentials:  true");
echo  "ok";

二、属性项

① readyState

这个是xhr对象的状态码,就像是一本史书一样,贯穿于整个xhr的使用历史,从最开始没有进行任何操作的时候为UNSENT,到OPENED,HEADERS_RECEIVED,LOADING,DONE的一步步变化,我们可以使用onreadystatechange这一回调函数来侦听它的变化,我们使用的最多的就是当它的值为4,也就是等于DONE的时候来对响应结果进行进一步的处理。

② status

由于xhr对象发送的是一个http请求,那么肯定就会有http的状态码,status就是代表了状态码,当一个请求成功的时候那么状态码就是2XX或者是304,2XX代表的是服务器成功响应了,304代表是从浏览器缓存中读取了内容。

javascript

if(xhr.readyState==4){
        if(xhr.status>=200&&xhr.status<300 ||="" xhr.status="=304){" console.log(xhr.response);="" }="" }<="" code="">
      

③ statusText

这个属性的作用其实不大,就是对上面的http状态码status进行一个描述,比如说200状态码的描述就是OK。

④ response

字面意思是响应,就是响应的主体,这个值依赖于responseType,不同的responseType就会使得response的类型不同。

下面是不同的responseType和response类型对照

① “” :空值代表response是一个 DOMString 类型的值。

② arraybuffer:response是一个 ArrayBuffer 类型的值。

③ blob:response是一个 Blob 类型的值。

④ document:response是一个 Document 类型的值。

⑤ json:response是一个JSON类型的值。

⑥ text:response是一个DOMString类型的值,与responseType是空值相同。

另外还有一些浏览器独有的值,如moz-chunked-text,moz-blob等等,这些都是某种浏览器没有标准化的内容,所以这里也就不赘述了,如果有兴趣可以阅读MDN的此篇文章-》
传送门

⑤ responseType

这就是响应的类型,在上面已经说过它与response的关系了,默认值就是为空。

⑥ responseURL

返回响应序列化的URL地址,如果URL是null就返回空字符串。如在上面最开始说withCredentials的时候的代码中的responseURL的值就是

“http://127.0.0.1/withCredentials.php”。

⑦ responseText

如果请求成功就是一个带有响应数据文本的DOMString,如果请求不成功那么这个值就是null。

⑧ responseXML

是一个包含响应数据的文档(document),如果请求失败或者是请求返回的内容不能解析为一个xml或者是html,那么这个值就是null。

⑨ upload

这是一个新的api,返回一个XMLHttpRequestUpload对象,表示上传过程。这个对象包含与xhr类似的回调函数,可以使用这些回调函数来监听数据发送过程中的进度(onprogress)、错误(onerror)、中断(onabort)等等。

可以使用这个对象来创建一个上传内容的进度监测:

javascript

var  xhr  =  new  XMLHttpRequest();
var  onProgressHandler  =  function(event)  {
        if(event.lengthComputable)  {
                console.log((event.loaded  /  event.total)  *  100);
        }  else  {
                console.log("Can"t  determine  the  size  of  the  file.");
        }
}
xhr.upload.addEventListener("progress",  onProgressHandler,  false);
xhr.open("POST","http://iwenku.net");
xhr.send(data);

三、方法项

① open

用于初始化一个请求,所有ajax请求的第一步都是要构建这么一个请求。在open方法之前xhr的readyState是UNSENT,当调用open方法之后就会变为OPENED。

open方法有5个参数,前两个是必须的,后面三个是可选的参数。

第一个是用的HTTP方法:可以传入“GET”、“POST”、“HEAD”等方法。

第二个参数是请求的地址。

第三个参数代表是不是异步(async),默认值为true,也就是使用异步的方式不阻塞主线程,如果值为false,则不使用异步的方式,在主线程知道xhr的请求结束之后才会继续执行后面的语句。下面有一段xhr的open方法异步和同步的示例:

javascript

var  xhr=new  XMLHttpRequest();
xhr.open("GET","http://127.0.0.1/openTest.php");
xhr.send(null);
xhr.onreadystatechange=function(){
        if(xhr.readyState===xhr.DONE){
                console.log("done");
        }
}
console.log("response"+xhr.responseText);
for(var  i=0;i<3;i++){ console.log(i);="" }<="" code="">
        

上面open方法没有传入第三个参数,也就是使用了默认值true,代表这是一个异步的请求,最后程序的输出为:

response:

0

1

2

done

如果在上面的代码中把open的第三个参数设置为false,那么就是使用同步的方式,程序的输出结果是:

response:ok

0

1

2

可以看出来不仅仅是在主线程中顺序执行了,而且readystatechange事件也没有侦听到。

② setRequestHeader

给指定的HTTP请求头赋值,这个方法如果要使用的话需要在open方法执行之后并且还没有执行send方法。

语法:setRequestHeader(请求头名称,要赋予的值)

这个方法其实很简单,之前在一个前端中级交流群里有个朋友提出来怎么来设置多个请求头,我和他说多次调用这个方法不就行了,其实自己偷偷的去查了一下能不能调用一次这个方法同时改变多个值,事实证明是不行的~。

③ send

发送请求. 如果在open中没有设置async参数,或者是这个参数设置为了true,那么在调用send方法后send方法会立即返回,不会阻塞主线程,然后继续执行后面的代码。如果在open的时候采用的是同步的方式,也就是把第三个参数设置为了false,那么send方法就会阻塞主线程,只有当请求结束的时候才会返回。

send方法可以不传入数据,也可以传入ArrayBuffer、Blob、Document、DOMString或者是FormData等类型的数据,当数据类型为document的时候,它在发送之前会进行序列化,在FireFox3之前编码总是会采用utf8,在这之后会根据body或者xmlEncoding的编码。

什么是序列化?

序列化是将对象状态转换为可保持或传输的格式的过程。在javascript中最常用的进行序列化的方法是JSON.stringify,反序列化可以使用JSON.parse来实现。

④ abort

如果请求已经被发送,则立刻中止请求。但是这个也只是让前端结束ajax请求,至于后台会不会也结束请求不再去执行某些操作,那么就得对后端进行设置了。

⑤ getResponseHeader

返回指定的响应头的值,如果响应头还没被接受,或该响应头不存在,则返回null。

语法:getResponseHeader(相应头名称)

javascript

var  xhr=new  XMLHttpRequest();
xhr.open("GET","http://127.0.0.1/getResponseHeader.php");
xhr.send(null);
xhr.onreadystatechange=function(){
        if(xhr.readyState===xhr.DONE){
                console.log(xhr.getResponseHeader("Content-Type"));
        }
}

上面这一段代码会输出”text/html“,也就是说在相应头中的Content-Type就是这个。

⑥ getAllResponseHeaders

这个方法和上面的getResponseHeader相类似,这个方法返回的是所有的头部信息,经过实际测试返回的内容数据类型为string。

⑦ overrideMimeType

在浏览器中显示的内容有 HTML、有 XML等等很多类型,浏览器就是使用MIME Type,也就是该资源的媒体类型来区分它们,来决定怎么显示。

媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过Content-Type 来表示的,例如:Content-Type: text/HTML表示内容是 text/HTML 类型,也就是超文本文件。

这个方法的作用就是重写由服务器返回的MIME type。这个可用于强制把一个响应流当作“text/xml”来处理和解析,即使服务器没有指明数据是这个类型。

这个方法需要在open之后,send方法之前进行调用。

四、回调项

① onabort

当一个xhr实例调用abort方法的时候会触发这个回调,用于处理中断了一个xhr请求之后的一些事情。这个回调函数会传入一个XMLHttpRequestProgressEvent类型的参数:

《XHR 对象实例所有的配置、属性、方法、回调和不可变值》
② onerror

当xhr出现错误的时候就会触发这个回调,也会传入一个XMLHttpRequestProgressEvent对象。

③ ontimeout

当请求的执行时间超过了timeout设置的时长的时候就会触发这个超时回调。

④ onreadystatechange

每当 XMLHttpRequest 的属性 readyState 发生改变时就会触发这个事件,但是根据实际测试如果open的时候这个ajax请求不是异步的,那么就不会触发这个事件。

当一个 XMLHttpRequest 请求被 abort() 方法取消时 readystatechange 事件也不会被触发。

还剩下4个回调,这四个都是关于progress的,所以在这里一起来写一下~

在 XHR2 (XMLHttpRequest Level 2) 的规范性已经定义了 Progress Event 事件,好让我们在发送异步请求的时候能够得知进度。

onloadstart:当process开始的时候触发。

onloadend:当process结束的时候。

onprogress:每次progress正在进行的时候触发,会传入一个XMLHttpRequestProgressEvent对象,可以从这个对象的total属性、loaded对象等来获取总大小和已经加载的大小。

onload:每次progress成功的时候触发。

博主即将本科毕业,目前已拿到阿里巴巴、腾讯等公司的前端实习Offer,如果您的团队在今年秋季校招的时候需要招收一名前端,可以与我联系,我的邮箱是:admin@iwenku.net,手机号是:17002905670,QQ是:82163514,谢谢~

    原文作者:HTTP
    原文地址: https://juejin.im/entry/575bdaec2e958a0069db5cff
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞