XMLHttpRequest Level 2的跨域功能(CORS) //另附JSONP的跨域实现

前端之家收集整理的这篇文章主要介绍了XMLHttpRequest Level 2的跨域功能(CORS) //另附JSONP的跨域实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

XMLHttpRequest Level 2的功能已经大幅提升了,
参见:http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html

我们知道,受到浏览器”同域限制“制约,以前的xhr对象是无法完成跨域请求的,而现在只需在Server端做一个访问控制,Client端再用xhr对象请求就行了,一般情况下Client并不需要设置,当然还有些相关的方法属性可供使用的,比如setRequestHeader,withCredentials。
服务端设置参见:https://developer.mozilla.org/en-US/docs/Server-Side_Access_Control

下面我们简单的做个demo
Server端代码(PHP):

  1. if($_SERVER['HTTP_ORIGIN']=="http://www.cssass.com")
  2. {
  3. header(Access-Control-Allow-Origin: http://www.cssass.com');
  4. Content-Type: text/plain REQUEST_METHODGET {
  5. $arr=array(
  6. id'=>1',
  7. nameXMLHttpRequest Response'
  8. );
  9. echo@H_301_130@json_encode($arr);
  10. };
  11. };

http响应头设置参见:https://developer.mozilla.org/en-US/docs/HTTP_access_control#The_HTTP_response_headers

Client端代码

正如你所知,ie下是不支持XMLHttpRequest Level 2的,不过ie8引入了自己的跨域对象XDomainRequest。(同时ie8下的xhr对象也引入了 timeou属性t和ontimeout方法
所以我们做下兼容(不支持ie6,ie7):

接下来,我们来了解下JSONP这种在同域限制的情况下实现跨域请求(GET)的实现过程。
原理其实就是:以script标签的形式在页面中放置一个请求地址,该请求地址返回的数据格式为:

jsonp1354513528560({“id”:”2″,”name”:”JSON with Padding”})

如果jsonp1354513528560是一个预先定义好的JS方法,那么获取其参数(我们实际需要获取的数据)就顺理成章了。

以下是Client端的实现代码:

(function(){
  • //jsonp的具体实现
  • var@H_301_130@randomNum=(newDate).@H_301_130@getTime(),64)"> @H_301_130@callName=null,204)">sendScriptRequest=function(@H_301_130@url,@H_301_130@id){
  • //将请求地址以script标签形式插入到页面。(注定是GET请求)
  • head=document.@H_301_130@getElementsByTagName(head")[0];
  • script=document.@H_301_130@createElement(script");
  • @H_301_130@script.@H_301_130@id=@H_301_130@id;
  • src=@H_301_130@url;
  • charset=utf-8';
  • head.@H_301_130@appendChild(@H_301_130@script);
  • },204)">buildTempFunction=callback){
  • //创建一个全局方法,并将方法名当做请求地址的一个参数
  • callName=jsonp"+@H_301_130@randomNum++;
  • window[@H_301_130@callName]=data){
  • @H_301_130@callback(@H_301_130@data);
  • window[@H_301_130@callName]=@H_301_130@undefined;
  • try{
  • deletewindow[@H_301_130@callName];
  • //var jsNode = document.getElementById(callName);
  • //jsNode.parentElement.removeChild(jsNode); //执行全局方法后,将script标签删除
  • }catch(@H_301_130@e){}
  • };
  • return@H_301_130@callName;
  • $@H_301_130@jsonp=params){
  • //生成GET请求地址
  • @H_301_130@params.@H_301_130@callback=@H_301_130@buildTempFunction(@H_301_130@callback);
  • url+=(@H_301_130@url.@H_301_130@indexOf(?")>0)?"":";
  • for(iin@H_301_130@params)
  • @H_301_130@url+=&i+=params[@H_301_130@i];
  • sendScriptRequest(@H_301_130@callName);
  • };
  • //对外开放接口:$jsonp
  • /**
  • * @$jsonp JSONP方法
  • * @param {String} url 请求地址
  • * @param {Object} params 请求参数
  • */
  • if(!window.$@H_301_130@jsonp)
  • window.$@H_301_130@jsonp= $@H_301_130@jsonp;
  • })();
  • Server端很简单,只需拼接输出一个js的执行方法即可。

    $jsonp=$_GET[callback'];//请求端传递的callback参数,作为输出方法
  • 2JSON with Padding );
  • echo$jsonp,($arr),0)">)';
  • 演示: