Chydar 2019-06-28
IE5是第一款引入XHR对象的浏览器,在IE5中,XHR对象是通过MSXML库中的一个ActiveX对象实现的
//适用于 IE7 之前的版本 function createXHR(){ if (typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i, len; for (i=0,len=versions.length; i < len; i++){ try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (ex){ //跳过 } } } return new ActiveXObject(arguments.callee.activeXString); }
IE7+、Firefox、Opera、Chrome、Safari都支持原生的XHR对象,这些浏览器中创建XHR对象,可以使用XMLHttpRequest构造函数
var xhr=new XMLHttpRequest();
如果还必须要支持IE的更早版本,可以在createHXR()函数中加入对原生XHR对象的支持
function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined"){ if (typeof arguments.callee.activeXString != "string"){ var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i, len; for (i=0,len=versions.length; i < len; i++){ try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (ex){ //跳过 } } } return new ActiveXObject(arguments.callee.activeXString); } else { throw new Error("No XHR object available."); } }
这个函数中新增的代码首先检测原生XHR对象是否存在,如果存在则返回它的新实例,如果原生对象不存在,则检测ActiveX对象,如果这两种对象都不存在,就抛出一个错误,然后就可以使用下面的代码在所有浏览器中创建XHR对象了
var xhr=createXHR();
在使用XHR对象时,要调用的第一个方法是open(),接收3个参数:要发送的请求的类型(get或者post)、请求的URL和表示是否异步发送请求的布尔值
xhr.open("get","example.php",false);
要想发送特定的请求,调用send()方法
xhr.open("get","example.txt",false); xhr.send(null);
响应的数据会自动填充XHR对象的属性
XHR对象的readyState属性表示请求响应过程的当前活动阶段
必须在调用open()之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性
var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("get", "example.txt", true); xhr.send(null);
在发送XHR请求的同时,还会发送下列头部信息
setRequestHeader()方法,可以设置自定义的请求头部信息,这个方法接收两个参数:头部字段名称和头部字段的值。要成功发送头部信息,必须在调用open()方法之后且调用send()方法之前调用setRequestHeader()
var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ 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.setRequestHeader("MyHeader", "MyValue"); xhr.send(null);
查询字符串中每个参数的名称和值都必须使用encodeURIComponent()进行编码,然后才能放到URL的末尾,而且所有的名-值对都必须由&分隔
xhr.open("get","example.php?name1=value1&name2=value2",true)
向现有URL的末尾添加查询字符串参数
function addURLParam(url, name, value) { url += (url.indexOf("?") == -1 ? "?" : "&"); url += encodeURIComponent(name) + "=" + encodeURIComponent(value); return url; }
POST请求,通常用于向服务器发送应该被保存的数据
function submitData(){ var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("post", "postexample.php", true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); var form = document.getElementById("user-info"); xhr.send(serialize(form)); }
FormData为序列化表单以及创建与表单格式相同的数据,提供了便利
var data=new FormData(); data.append("name","Nicholas");
创建了FormData的实例后,可以将它直接传给XHR的send()方法
var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(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));
IE8为XHR对象添加了一个timeout属性,表示请求在等待响应多少毫秒之后就会终止,在给timeout设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序
var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ try { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } catch (ex){ //假设由 ontimeout 事件处理程序处理 } } }; xhr.open("get", "timeout.php", true); xhr.timeout = 1000; // 将超时设置为 1 秒钟(仅适用于 IE8+ ) xhr.ontimeout = function(){ alert("Request did not return in a second."); }; xhr.send(null);
通过调用overrideMimeType()方法,可以保证把响应当做XML而非纯文本来处理
var xhr = createXHR(); xhr.open("get", "text.php", true); xhr.overrideMimeType("text/xml"); xhr.send(null);
6个进度事件
var xhr = createXHR(); 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", "altevents.php", true); xhr.send(null);
var xhr = createXHR(); xhr.onload = function(event){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(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", "altevents.php", true); xhr.send(null);
微软在IE8中引入了XDR类型,这个对象与XHR类型,但是能实现安全可靠的跨域通信
所有XDR请求都是异步执行的,不能用它来创建同步请求,请求返回之后,会触发load事件,响应的数据也会保存在responseText属性中
var xdr = new XDomainRequest(); xdr.onload = function(){ alert(xdr.responseText); }; xdr.open("get", "http://www.somewhere-else.com/page/"); xdr.send(null)
请求返回前调用abort()方法可以终止请求
xdr.abort();//终止请求
与XHR一样,XDR对象也支持timeout属性以及ontimeout事件处理程序
var xdr = new XDomainRequest(); 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.somewhere-else.com/page/"); xdr.send(null);
为支持POST请求,XDR对象提供了contentType属性,用来表示发送数据的格式
var xdr = new XDomainRequest(); xdr.onload = function(){ alert(xdr.responseText); }; xdr.onerror = function(){ alert("An error occurred."); }; xdr.open("post", "http://www.somewhere-else.com/page/"); xdr.contentType = "application/x-www-form-urlencoded"; xdr.send("name1=value1&name2=value2");
要请求位于另一个域中的资源,使用标准的XHR对象并在open()方法中传入绝对URL
var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("get", "http://www.somewhere-else.com/page/", true); xhr.send(null);
安全限制
这种请求使用OPITONS方法,发送下列头部
Origin: http://www.nczonline.net Access-Control-Request-Method: POST Access-Control-Request-Headers: NCZ
服务器可以决定是否允许这种类型的请求,服务器在响应中发送如下头部与浏览器进行沟通
Access-Control-Allow-Origin: http://www.nczonline.net Access-Control-Allow-Methods: POST, GET Access-Control-Allow-Headers: NCZ Access-Control-Max-Age: 1728000
通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据
Access-Control-Allow-Credentials:true
function createCORSRequest(method, url){ var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr){ xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined"){ vxhr = new XDomainRequest(); xhr.open(method, url); } else { xhr = null; } return xhr; } var request = createCORSRequest("get", "http://www.somewhere-else.com/page/"); if (request){ request.onload = function(){ //对 request.responseText 进行处理 }; request.send(); }
Firefox、Safari和Chrome中的XMLHttpRequest对象与IE中的XDomainRequest对象类似,都提供了够用的接口,这两个对象共同的属性方法如下
通过图像Ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,它能知道响应什么时候接收到的
var img = new Image(); img.onload = img.onerror = function(){ alert("Done!"); }; img.src = "http://www.example.com/test?name=Nicholas";
JSONP由两部分组成:回调函数和数据,回调函数是当响应到来时应该在页面中调用的函数,回调函数的名字一般是在请求中指定的,而数据就是传入回调函数中的JSON数据
function handleResponse(response){ alert("You’re at IP address " + response.ip + ", which is in " + response.city + ", " + response.region_name); } var script = document.createElement("script"); script.src = "http://freegeoip.net/json/?callback=handleResponse"; document.body.insertBefore(script, document.body.firstChild);
两种实现Comet的方式
长轮询
流
在页面的整个生命周期内只使用一个HTTP连接,具体来说就是浏览器向服务器发送一个请求,而服务器保持连接打开,然后周期性的向浏览器发送数据
function createStreamingClient(url, progress, finished){ var xhr = new XMLHttpRequest(), received = 0; xhr.open("get", url, true); xhr.onreadystatechange = function(){ var result; if (xhr.readyState == 3){ //只取得最新数据并调整计数器 result = xhr.responseText.substring(received); received += result.length; //调用 progress 回调函数 progress(result); } else if (xhr.readyState == 4){ finished(xhr.responseText); } }; xhr.send(null); return xhr; } var client = createStreamingClient("streaming.php", function(data){ alert("Received: " + data); }, function(data){ alert("Done!"); });
SSE是围绕只读Comet交互推出的API或者模式
var source=new EventSource("myevents.php");
另外还有三个事件
要创建Web Socket,先实例一个WebSocket对象并传入要连接的URL
var socket = new WebSocket("ws://www.example.com/server.php");
实例化WebSocket对象后,浏览器会马上尝试创建连接,与XHR类似,WebSocket也有一个表示当前状态的readyState属性,这个属性的值与XHR并不相同
要关闭Web Socket连接,可以在任何时候调用close()方法
socket.close();
使用send()方法并传入任意字符串
var socket = new WebSocket("ws://www.example.com/server.php"); socket.send("Hello world!"); //将数据序列化为JSON字符串,然后发送到服务器 var message = { time: new Date(), text: "Hello world!", clientId: "asdfp8734rew" }; socket.send(JSON.stringify(message)); //当服务器收到消息时,WebSocket对象就会触发message事件,这个message事件与其他传递消息的协议类似,也是把返回的数据保存在event.data属性中 socket.onmessage = function(event){ var data = event.data; //处理数据 };
其他事件
var socket = new WebSocket("ws://www.example.com/server.php"); socket.onopen = function(){ alert("Connection established."); }; socket.onerror = function(){ alert("Connection error."); }; socket.onclose = function(){ alert("Connection closed."); };
考虑是使用 SSE 还是使用 Web Sockets 时,可以考虑如下几个因素。
为确保通过 XHR 访问的 URL 安全,通行的做法就是验证发送请求者是否有权限访问相应的资源
结束数据方法的参数,该如何定义?-- 集合为自定义实体类中的结合属性,有几个实体类,改变下标就行了。<input id="add" type="button" value="新增visitor&quo
本文实例讲述了php+ ajax 实现的写入数据库操作。分享给大家供大家参考,具体如下:。<input class="tel" type="text" placeholder="请输入您的手机号码&q