您的位置:首页 > 理论基础 > 计算机网络

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响应头部确定的预期字节数

利用这些信息,我们可以为用户创建一个进度指示器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: