You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
varxhr=newXMLHttpRequest();xhr.onreadystatechange=function(){if(xhr.readyState==4){if((xhr.status>=200&&xhr<300)||xhr.status==304){console.log(xhr.responseText);}else{console.log("Request was unsuccessful: "+xhr.status);}}};xhr.open('post','example.php',true);varform=document.getElementById('user-info');xhr.send(newFormData(form));
varxhr=newXMLHttpRequest();xhr.onreadystatechange=function(){if(xhr.readyState==4){try{if((xhr.status>=200&&xhr<300)||xhr.status==304){console.log(xhr.responseText);}else{console.log("Request was unsuccessful: "+xhr.status);}}catch(ex){//由ontimeout事件处理程序处理}}};xhr.open('get','timeout.php',true);xhr.timeout=1000;//将超时设置为1秒,仅适用IE8+xhr.ontimeout=function(){console.log('request did not return in a second');xhr.send(null);}
varxhr=newXMLHttpRequest();xhr.onload=function(){if((xhr,status>=200&&xhr.status<300)||xhr.status==304){alert(xhr.responseText);}else{alert("Request was unsuccessful: "+xhr.status);}};xhr.open('get','example.php',true);xhr.send(null);
varxhr=newXMLHttpRequest();xhr.onload=function(){if((xhr,status>=200&&xhr.status<300)||xhr.status==304){alert(xhr.responseText);}else{alert("Request was unsuccessful: "+xhr.status);}};xhr.onprogress=function(event){vardivStatus=document.getElementById('status');if(event.lengthComputable){divStatus.innerHTML='Received'+event.position+' of '+event.totalSize+'bytes';}};xhr.open('get','example.php',true);xhr.send(null);
varxdr=newXDomainRequest();xdr.onload=function(){alert(xdr.responseText);};xdr.onerror=function(){alert("an error occurred.");}xdr.timeout=1000;xdr.ontimeout=function(){alert("request took too long");}xdr.open('get','http://www.xx.net/page/');xdr.send(null);
varxhr=newXMLHttpRequest();xhr.onreadystatechange=function(){if(xhr.readyState==4){if((xhr.status>=200&&xhr<300)||xhr.status==304){console.log(xhr.responseText);}else{console.log("Request was unsuccessful: "+xhr.status);}}};xhr.open('get','http://www.xx.net/page',true);xhr.send(null);
Access-Control-Request-Origin: http://www.nczonline.net Access-Control-Request-Method: POST, GET Access-Control-Request-Headers: NCZ Access-Control-Max-Age1728000
前言
一直都Ajax都比较模糊。就了解一些简单的。但是又觉得好复杂,一点都不想知道,所以想到了一个方法,边看书,边把每一个字都打出来。这样就会强迫自己学下来。这个方法还是很管用的。发现ajax还是不是那么不可理解。慢慢有点理解了。
XMLHttpRequest2级
FormData
FormData类型为序列化表单以及创建表单格式相同的数据(用于通过XHR传输)提供了便利。
看一个例子
append方法,接受两个参数,键和值。分别对应表单字段的名字和字段中包含的值。可以添加任意多个键值对。而通过向FormData构造函数中传入表单元素,也可以用表单元素的数据预先向其中填入键值对。
创建了FormData的实例后,可以将它直接传给XHR的send方法。例如
使用FormData的方便在于,不必明确的在XHR对象上设置请求头部。XHR对象能够识别传入的数据类型是FormData的实例。
超时设定
XHR对象添加了一个timeout的属性,表示请求在等待响应多少毫秒之后就终止。在给timeout设置一个数组后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序。
在这个例子中,表示如果请求在1秒钟内没有返回,就自动终止。请求终止时,会调用ontimeout事件处理程序,但此时readyState可能已经改变为4,这意味着会调用onreadystatechange事件处理程序,可是,如果在超时终止请求之后再访问status属性,就会导致错误。为了避免浏览器的错误报告,可以将检查status属性的语句封装在一个try-catch语句中。
overrideMimeType()方法
该方法用于重写XHR响应的MIME类型。例如,服务器返回的MIME类型是text/plain,但数据中实际包含的是XML。根据MIME类型,即使数据是XML,responseXML属性中仍然是null,通过调用该方法,可以保证把响应当做XML而非纯文本来处理。
在这里,强迫把XHR对象将响应当做XML而非纯文本来处理。调用overrideMimeType()必须在send()方法之前。才能保证重写响应的MIME类型。
进度事件
Progress Events规范是W3C的一个工作草案,定义了与客户端服务器通信有关的事件。这些事件最早其实只针对XHR操作,但目前也被其他API借鉴。有以下6个事件。
每一个请求都是从loadstart事件开始,接下来是一个或者多个progress事件,然后触发error,abort,或者load事件中的一个,最后触发loaded事件结束。
load事件
load事件,用于代替onreadystatechange事件。响应接受完毕后触发load事件,因此没有必要去检查readyState属性。而onload事件处理程序会接受到一个event对象,其target属性就指向XHR对象实例。
因此可以访问XHR对象的所有方法和属性。但是并非所有浏览器都为这个事件实现了适当的事件对象。
所有开发人员不得不像下面这样被迫使用XHR对象变量。
只有浏览器接受到服务器的响应,不管其状态如何,都会触发load事件。而这意味着必须要检查status属性,才能确定数据是否真的已经可用。
progress事件
这个事件会在浏览器接收新数据期间周期性地触发。而onprogress事件处理程序会接受到一个event对象,其target属性是XHR对象,但包含着三个额外的属性:lengthComputable、position和totalSize.其中,lengthComputable是一个表示进度是否可用的布尔值,position表示已经接收的字节数,totalSize表示根据Content-Length响应头部确定的预期字节数。
这样就可以给用户创建一个进度指示器。
为了确保正常执行,必须在调用open()方法之前添加onprogress事件处理程序。
跨源资源共享(Cross-Origin Resource Sharing)
定义了在必须访问跨源资源时,浏览器与服务器之间该如何沟通。CORS基本的思想是:就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或者响应是该成功还是失败。
例如,一个简单的使用GET或者POST发送的请求,它没有自定义的请求头部,而主体内容是text/plain,在发送该请求时,需要给它附加一个额外的Origin头部,其中包含请求页面的源信息(协议,域名,端口)以便服务器根据这个头部信息来决定是否给予响应
Origin: http://www.xxx.net
Origin头部的一个示例如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的源信息(如果是公共资源,可以回发‘*’)
Access-Control-Allow-Origin: http://www.xxx.net
如果没有这个头部,或者这个头部信息不匹配,浏览器就会驳回请求。注意,请求和响应都不包含cookie信息。
IE对CORS的实现
在IE8中引入了XDR(XDomainRequest)类型,这个对象与XHR类似,但是能实现安全可靠的跨域通信。
它与XHR的区别在于:
被请求的资源可以根据它认为合适的任意数据(用户代理,源页面)来决定是否设置Access-Control-Allow-Origin头部,作为请求的一部分,Origin头部的值表示请求的来源域,以便远程资源明确地识别XDR请求。
XDR对象的使用方法:
除了错误本身之外,没有其他可用的信息可用,因此唯一能够确定的就只要请求为成功。由于导致XDR请求失败的因素很多,因此可以通过onerror事件处理程序来捕获该事件,否则,即使请求失败也不会有任何提示。
在请求返回之前可以调用abort()方法来终止请求
xdr.abort()
;与XHR一样,XDR对象也支持timeout属性以及ontimeout事件处理程序。
为了支持POST请求,XDR对象提供了contentType属性,用来表示发送数据的格式。
其他浏览器对CORS的实现
通过XMLHttpRequest对象实现了对CORS的原生支持。在尝试打开不同来源的资源时,无需额外编写代码,就可以触发这个行为。要请求位于另一个域中的资源,使用标准的XHR对象并在open()方法中传入绝对URL即可。
与IE中XDR对象不同的是,通过跨域XHR对象可以访问status和statusText属性,而且还支持同步请求,跨域XHR对象也有一些限制。
由于无论同源请求还是跨源请求都支持相同的接口,因此本地资源,最好使用相对URL,在访问远程资源再使用绝对URL,这样能消除歧义,避免出现访问限制头部或者本地cookie信息等问题。
Preflighted Requests
CORS通过一种叫Preflighted Requests的透明服务器验证机制支持开发人员使用自定义的头部、GET或POST之外的方法,以及不同类型的主体内容。在使用下列高级选项来发送请求时,就会向服务器发送一个Preflight请求,这种请求使用OPTIONS方法。发送下列头部。
例如:一个带有自定义头部NCZ的使用的POST方法发送的请求
Origin: http://www.nczonline.net Access-Control-Request-Method: POST Access-Control-Request-Headers:NCZ
发送这个请求后,服务器可以决定是否允许这种类型的请求。服务器通过在响应中发送如下头部与浏览器进行沟通。
例如:
Access-Control-Request-Origin: http://www.nczonline.net Access-Control-Request-Method: POST, GET Access-Control-Request-Headers: NCZ Access-Control-Max-Age1728000
Preflight 请求结束后,结果将按照响应中指定的时间缓存起来,而为此付出的代价只是第一次发送这种请求时会多一次HTTP请求。IE10及更早的版本都不支持。
带凭据的请求
默认情况下,跨源请求不提供凭据(cookie, HTTP认证及客户端SSL证明等)。通过将withCredentials属性设置为true。可以指定某个请求应该发送的凭据。如果服务器接受带凭据的请求,会用下面的HTTP头部来响应。
Access-Control-Allow-Credentials: true
如果发送的是带凭据的请求,但是服务器的响应中没有包含这个头部,那么浏览器就不会把响应交给javascript(于是,responseText中将是空字符串,status状态为0,而且会调用onerror()事件处理程序),另外,服务器还可以在Preflight响应中发送这个HTTP头部。表示允许源发送带凭据的请求。
跨浏览器的CORS
检测XHR是否支持CORS的最简单方式,就是检查是否存在withCredentials属性,再结合检测XDomainRequest对象是否存在。就可以兼顾所有浏览器了。
Firefox、Safari、Chrome中的XMLHttpRequest对象与IE中的XDomainRequest对象类似,都提供够用的接口,因此以上模式还是相当有用的。这两个对象共同的属性和方法如下:
The text was updated successfully, but these errors were encountered: