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