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.abc.com/page/", true); xhr.send(null);
与IE不同,通过跨域XHR对象可以访问status属性和statusText属性,也可同步请求。
7-3-1.跨域XHR的限制:
①不能使用setRequestHeader()设置自定义头部;
②不能发送和接收cookie;
③调用getAllResponseHeader()方法总会返回空字符串。
7-3-2.无论同源请求还是跨域请求都是使用相同的接口,故对于本地资源,最好用相对URL,对远程资源再用绝对URL。
这样能消除歧义,避免出现限制访问头部或本地cookie信息等问题。
7-4、跨浏览器的CORS(IE8+、FF等)
检测XHR是否支持CORS的方法:检查是否存在withCredentials属性,在结合检测XDomainRequest对象是否存在。
CORS跨域兼容
function createCORSRequest(method, url){ var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr){ xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined"){ xhr = new XDomainRequest(); xhr.open(method, url); } else { xhr = null; } return xhr; } var request = createCORSRequest("get", "http://www.somewhere-else.com/xdr.php"); if (request){ request.onload = function(){ //do something with request.responseText }; request.send(); }
上述createCORSRequest()函数返回的对象的属性(XHR和XDR的共同属性):
①abort():停止正在进行的请求;
②onerror:用于替代onreadystatechange检测错误;
③onload:用于代替onreadystatechange检测成功;
④responseText:用于取得响应内容;
⑤send():用于发送请求。
8、其他跨域技术
在CORS出现前,常利用DOM中能够执行跨域请求的功能,在不依赖XHR对象时,也能发送某种请求。
与COSR不同的是,不用修改服务器代码。
8-1.图像Ping
使用<img>标签,由于可以从任何网页加载图像,故常是在线广告跟踪浏览量的只要方式。
可动态创建图像,使用它们的onload和onerror事件句柄,确定是否接受到了响应。
var img = new Image(); img.onload = img.onerror = function(){ alert("Done!"); }; img.src = "http://www.example.com/test?name=Nicholas";
图像Ping是与服务器进行简单、单向的跨域通信的一种方式。请求的数据通过查询字符串形式发送,响应可以是任何内容,通常是像素图或204响应。虽然通过图像Ping,浏览器得不到任何具体数据,但通过侦听load和error事件,能找到响应收到的时间。
图像Ping常用于跟踪用户点击页面 或动态广告曝光次数。
缺点:①只能发送GET请求;②无法访问服务器响应文本。
8-2.JSONP
JSONP(JSON width Padding)填充式JSON或参数式JSON,类似JSON,是包含在函数调用中的JSON:
callback( {"name" : "value"} );
8-2-1.JSONP有两个部分:回调函数 和 数据
回调函数:当响应到来时应该在页面中调用的函数。回调函数的名称在请求中指定。
数据:传入回调函数的JSON数据。
8-2-2.JSONP通过动态<script>元素,为其src属性指定一个跨域的URL。类似<img>元素,即都能不受限制地跨域加载资源。
JSONP为有效的JavaScript代码,在请求完成即JSONP响应 加载到页面后就会立即执行。
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);
headleResponse()为回调函数,将在响应到来后执行。
8-2-3.JSONP之所以流行,是因为 :
①能够直接访问响应文本;
②支持浏览器与服务器之间的双向通信。
不足:
①JSONP从其他域加载代码执行,因此该域必须安全可靠;
②很难确保JSONP请求是否失败。
8-3Comet ”服务器推送" 【不兼容IE】
Ajax从页面想服务器请求数据,Comet则是服务器向页面推送数据,Comet能近乎实时地向页面推送信息。
8-3-1.实现Comet的2种方式:长轮询 和 流