XMLHttpRequest和 FormData实现Ajax
#什么是 XMLHttpRequest 对象?XMLHttpRequest 对象用于在后台与服务器交换数据,能够:
所有现代的浏览器都支持 XMLHttpRequest 对象。 #创建 XMLHttpRequest 对象所有现代浏览器 (IE7+、Firefox、Chrome、Safari 以及 Opera) 都内建了 XMLHttpRequest 对象。 通过一行简单的 JavaScript 代码,我们就可以创建 XMLHttpRequest 对象。 创建 XMLHttpRequest 对象的语法:xmlhttp = new XMLHttpRequest(); 老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
XhrController.class.php
<?php namespace HomeController; use ThinkController; class XhrController extends Controller { public function index() { echo 'This is responseText!'; } }
数据流:
数据流方式就是在建立的连接断开之前,也就是 readystate 状态为 3 的时候接受数据。麻烦的事情也在这里,因为数据正在传输,你拿到的 xhr.response 可能就是半截数据,所以呢,最好定义一个数据传输的协议,比如前2个字节表示字符串的长度,然后你只获取这个长度的内容,接着改变游标的位置。 假如数据格式为: data splitChar(data为数据内容;splitChar为数据结束标志,长度为1)。 那么传输的数据内容为 data splitChar data splitChar data splitChar... var dataStream = function(type,url) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { // 状态为 3,数据接收中 if (xhr.readyState == 3) { var i,l,s; s = xhr.response; //读取数据 l = s.length; //获取数据长度 //从游标位置开始获取数据,并分割数据 s = s.slice(p,l - 1).split(splitChar); //循环并操作数据 for (i in s) if (s[i]) deal(s[i]); //更新游标位置 p = l; } // 状态为 4,数据传输完毕,重新连接 if (xhr.readyState == 4) { xhr.onreadystatechange = null; dataStream(type,url); } }; xhr.open(type,true); xhr.send(); }; 这个代码写的是存在问题的,当 readystate 为 3 的时候可以获取数据,但是这时获取的数据可能只是整体数据的一部分,那后半截就拿不到了。但 readystate 在数据传输完毕之前是不会改变的,也就是说并不会继续接受剩下的数据。我们可以定时去监听readystate。这样的处理不算复杂,但是低版本IE不允许在readystate为3的时候读取数据,所以我们必须利用iframe照样可以异步获取数据,对于低版本IE可以使用iframe来接受数据流。 if (isIE) { var dataStream = function(url) { var ifr = document.createElement("iframe"),doc,timer; ifr.src = url; document.body.appendChild(ifr); doc = ifr.contentWindow.document; timer = setInterval(function() { if (ifr.readyState == "interactive") { // 处理数据,同上 } // 重新建立链接 if (ifr.readyState == "complete") { clearInterval(timer); dataStream(url); } },16); }; }; 定时去监听iframe的readystate的变化,从而获取数据流。不过还是存在问题。数据流实现“服务器推”数据的原理是就是文档(数据)还没有加载完,浏览器去服务器拿数据完成文档(数据)加载,我们就是利用这点,给浏览器塞点东西过去。 所以上述利用iframe的方式获取数据,会使浏览器一直处于加载状态,title上的那个圈圈一直在转动,鼠标的状态也是loading,这看着是相当不爽的。幸好,IE提供了HTMLFile对象,这个对象就相当于一个内存中的Document对象,它会解析文档。所以我们创建一个HTMLFile对象,在里面放置一个IFRAME来连接服务器。这样,各种浏览器就都支持了。 if (isIE) { var dataStream = function(url) { var doc = new ActiveXObject("HTMLFile"),ifr = doc.createElement("iframe"),timer,d; doc.write("<body/>"); ifr.src = url; doc.body.appendChild(ifr); d = ifr.contentWindow.document; timer = setInterval(function() { if (d.readyState == "interactive") { // 处理数据,同上 } // 重新建立链接 if (d.readyState == "complete") { clearInterval(timer); dataStream(url); } },16); }; };
#FormData类型可以用于构造表单数据
比起普通的Ajax,使用FormData的最大优点就是可以
异步上传一个二进制文件
构造方法:
new FormData(optional HTMLFormelement form)
参数:可选,是一个表单元素,可以包含任何形式的表单控件
给当前FormData对象添加一个键值对:
参数:
示例:
var formData = new FormData(); formData.append('username','张三'); formData.append('email','zhangsan@example.com'); formData.append('birthDate',1940); xhr.send(formData);
上面这段代码和下面这段的效果是一样的:
<html> <head></head> <body> <form id="registration" name="registration" action="/register"> <input type="text" name="username" value="张三" /> <input type="email" name="email" value="zhangsan@example.com" /> <input type="number" name="birthDate" value="1940" /> <input type="submit" onclick="return sendForm(this.form);" /> </form> </body> </html>
FormData对象还可以对现有的表单添加数据
function sendForm(form) { var formData = new FormData(form); formData.append('csrf','e69a18d7db1286040586e6da1950128'); var xhr = new XMLHttpRequest(); xhr.open('POST',form.action,true); xhr.onload = function(e) { //... }; xhr.send(formData); return false; } var form = document.querySelector('#registration'); sendForm(form);
FormData对象也能模拟File控件,进行文件上传
var oMyForm = new FormData(); oMyForm.append("username","Groucho"); oMyForm.append("accountnum",123456); // fileInputElement中已经包含了用户所选择的文件 oMyForm.append("userfile",fileInputElement.files[0]); var oFileBody = "<a id="a "><b id="b ">hey!</b></a>"; // Blob对象包含的文件内容 var oBlob = new Blob([oFileBody],{ type: "text/xml" }); oMyForm.append("webmasterfile",oBlob); var oReq = new XMLHttpRequest(); oReq.open("POST","http://foo.com/submitform.php"); oReq.send(oMyForm); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |