XMLHttpRequest 2级学习
2016-04-12 21:15
633 查看
老版本的缺点
老版本的XMLHttpRequest对象有以下几个缺点:只支持文本数据的传送,无法读取和上传二进制文件。
传送和接收数据时,没有进度信息,只能提示有没有完成。
受到”同域限制”,只能向同一域名的服务器请求数据。
新版本的功能
新版本的XMLHttpRequest对象的一些新功能:可以设置HTTP请求的时限。
可以使用FormData对象管理表单数据。
可以上传文件。
可以请求不同域名下的数据(跨域资源共享,Cross-origin resource sharing,简称 CORS)。
可以获取服务器端的二进制数据。
可以获得数据传输的进度信息。
FormData
XMLHttpRequest 2级定义了FormData类型,这为序列化表单以及创建与表单格式相同的数据提供了便利。新建FormData对象:
var formData = new FormData();
为它添加表单项:
formData.append('name', 'lisi'); formData.append('age', 12);
最后,直接传送这个FormData对象。这与提交网页表单的效果,完全一样。
xhr.send(formData);
Demo:
<!DOCTYPE html> <html> <head> <title>FormData</title> <meta charset="utf-8"> </head> <body> <p>Fill in the form below:</p> <form id="user-info"> <label for="user-name">姓名:</label> <input type="text" id="user-name" name="user-name" /><br> <label for="user-email">Email:</label> <input type="text" id="user-email" name="user-email" /><br> <input type="button" value="Submit" onclick="submitData()" /> </form> <script type="text/javascript"> function createXHR(){ if(typeof XMLHttpRequest){ return new XMLHttpRequest(); }else if(typeof ActiveXObject){ return new ActiveXObject("Microsoft.XMLHTTP"); } } function submitData(){ var xhr = createXHR(); xhr.onreadystatechange = function(event){ if (xhr.readyState == 4){ if (xhr.status == 200 ){ console.log(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("post", "postexample.php", true); var form = document.getElementById("user-info"); xhr.send(new FormData(form)); } </script> </body> </html>
postexample.php
<?php header("Content-Type: text/plain"); echo <<<EOF Name: {$_POST['user-name']} Email: {$_POST['user-email']} EOF; ?>
使用FormData的方便之处在于:不必明确在xhr对象上设置请求头部,xhr对象能够识别传入的数据类型是FormData的实例,并配置适当的头部信息。
FormData对象也可以用来获取网页表单的值:
var form = document.getElementById('myform'); var formData = new FormData(form); formData.append('name', 'lisi'); // 添加一个表单项 xhr.open('POST', form.action); xhr.send(formData);
超时设定
新版本的XMLHttpRequest对象,增加了timeout属性,可以设置HTTP请求的时限,表示请求在等待响应多少毫秒之后就停止。在给timeout属性属性设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序。Demo:
<!DOCTYPE html> <html> <head> <title>Timeout事件</title> <meta charset="utf-8"> </head> <body> <script type="text/javascript"> function createXHR(){ if(typeof XMLHttpRequest){ return new XMLHttpRequest(); }else if(typeof ActiveXObject){ return new ActiveXObject("Microsoft.XMLHTTP"); } } var xhr = createXHR(); xhr.onreadystatechange = function(event){ try { if (xhr.readyState == 4){ if (xhr.status == 200){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } } catch (ex){ //assume handled by ontimeout } }; xhr.open("get", "timeout.php", true); xhr.timeout = 1000;//给xhr对象设置了timeout属性,表示请求在等待响应1000毫秒之后停止 xhr.ontimeout = function(){ alert("Request did not return in a second."); }; xhr.send(null); </script> </body> </html>
跨域资源共享(CORS)
新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做”跨域资源共享”(Cross-origin resource sharing,简称CORS)。使用”跨域资源共享”的前提,是浏览器必须支持这个功能,而且服务器端必须同意这种”跨域”。如果能够满足上面的条件,则代码的写法与不跨域的请求完全一样。
例如:
xhr.open('post', 'http://localhost/test.php',true);
进度事件
有一下6个进度事件:loadstart:在接收到响应数据的第一个字节时触发
progress:在接收响应期间持续不断地触发
error:在请求发生错误时触发
abort:在因为调用abort()方法而终止连续时触发
load:在接收到完整的响应数据时触发
loadend:在通信完成或者触发error、abort或load事件后触发
每个请求都是从触发loadstart事件开始,接下来是一或多个progress事件,然后触发error、abort或load事件中的一个,最后以触发loadend事件结束。
Demo:
<!DOCTYPE html> <html> <head> <title>XHR Progress Event Example</title> </head> <body> <div id="status"></div> <script type="text/javascript"> function createXHR(){ if(typeof XMLHttpRequest){ return new XMLHttpRequest(); }else if(typeof ActiveXObject){ return new ActiveXObject("Microsoft.XMLHTTP"); } } //主要浏览器接收到了服务器的响应,不管其状态如何,都会触发load事件。 window.onload = function(){ var xhr = createXHR(); xhr.onload = function(event){ if (xhr.status == 200){ console.log(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } }; xhr.onprogress = function(event){ var divStatus = document.getElementById("status"); if (event.lengthComputable){ divStatus.innerHTML = "Received " + event.position + " of " + event.totalSize + " bytes"; } }; xhr.open("get", "test.php", true); xhr.send(null); }; </script> </body> </html>
test.php
<?php header("Content-Type: text/plain"); header("Content-Length: 27"); echo "Some data"; flush(); echo "Some data"; flush(); echo "Some data"; flush(); ?>
progress事件会在浏览器接收新数据期间周期性地触发。onprogress事件处理程序会接收到一个event对象,其target属性是XHR对象,包含三个额外的属性:
lengthComputable:表示进度信息是否可用的布尔值
position:表示已经接收的字节数
totalSize:表示根据Content-Length响应头部确定的预期字节数
利用这些信息,我们可以为用户创建一个进度指示器
相关文章推荐
- 正则表达式基础入门学习http://deerchao.net/tutorials/regex/regex.htm
- Android 6.0中"Unable to find optional library: org.apache.http.legacy"错误解决
- Android读取网络图片到本地的简约的实现
- Android读取网络图片到本地的简约的实现
- 《UNIX网络编程》例子程序中所使用的 包裹函数 及 部分常量
- 广东工业大学2016校赛决赛-网络赛 A题 Krito的讨伐
- HTTPS原理(转)
- TCP协议中的三次握手和四次挥手(图解)
- 关于解决HTTP Status 405 - HTTP method POST is not supported by this URL方法之一
- CentOS6网络配置
- 10分钟理解TCP/IP各个协议以及协议之间的关系
- HTTP Content-type
- HttpClient介绍
- VijosP1595:学校网络(有向图变强连通图)
- http状态码详解
- JAVA网络编程
- 【B/S】HTTP错误500.23-Internal Server Error
- 安卓MVP设计思想,结合greendao+okhttp通过一个登陆的例子来进行学习(eclipse篇)
- 嵌入式 hi3518平台获取网络环境中的ip、netmask、broadcast等信息
- 嵌入式 hi3518平台以太网网络模块设计包括重连机制和网线检测机制