跨域访问

来源:互联网 发布:小米mix2全球网络制式 编辑:程序博客网 时间:2024/05/19 11:50


  1、什么是跨域访问?

    (1).同一父域名,不同域名之间的访问,包括同域名不同端口,如xx.com与yy.xx.com,xx:8088.com与xx:9200.com

    (2).完全不同的域名,如xx.com与yy.com


  2、我们为什么要解决跨域?

        (1) 我们自己的系统需要把不同资源放在不同服务器上,如AJAX请求,邮件系统获取通讯录人信息;

        (2) 自己的系统访问别人的系统。


  3、相关的解决方案?

XMLHttpRequest是浏览器的接口 最早是IE5上出现的

老版本问题:

(1)只支持文本数据的传送,无法用来读取和上传二进制文件。

 (2) 传送和接收数据时,没有进度信息,只能提示有没有完成。

  (3) 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据。

       新版本:

     Cross-origin resource sharing,简称CORS:浏览器必须支持这个功能,而且服务器端必须同意这种"跨域"IE10以及以上的

  服务器端设置Access-Control-Allow-Origin


IE8-IE9进行跨域请求时:

var xdr = new XDomainRequest();

IE5-IE6采用

new ActiveXObject("Microsoft.XMLHTTP");

    (1)同父或同根域名,可以采用document.domain="根域名",两个服务中的页面都进行设置,对于最新y

    a、  当浏览器不支持ajax访问时,可以采用iframe的方式,调用请求方的proxy.htm页面,在proxy.htm页面进行访问,在proxy.htm加载完成后,调用相关ajax访问

          http:// YY/A.htm

           <body>

          <iframe src="http://A.XX/proxy.htm"> </ifame>

         <script>

        调用proxy.htm中方法,传入调用的接口

         </script>

  b、对于像

     (3) 采用在服务器端访问不同的域名,但是这样会增加请求与转向

     (4)利用JSONP,JSON with padding 用img script 与link进行跨域请求 <script src="http://a/b/xx?jsonp=callback"></script>,其中jquery也有相应实现;

         如:

          1. $.getJSON

  <script>
  $(document).ready(function(){
  $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",
  function(data){
  $.each(data.items, function(i,item){
  $("<img/>").attr("src", item.media.m).appendTo("#images");
  if ( i == 3 ) return false;
  });
  });
  });
  </script>
  jsoncallback=?,其中?会自动替换为function(data)函数。
  2. $.ajax
  $.ajax({
  dataType: 'jsonp',
  data: 'id=10',
  jsonp: 'jsonp_callback',
  url: 'http://www.yiwuku.com/getdata',
  success: function () {
  // do stuff
  },
  });

     (5) 采用location.hash="#asdf"的值进行处理

      

URL.hash(fragment id) 解决方案

一个 URL 由几部分组成,如下图 2 所示:


图 2. URL 组件
带下划线的 URL 的屏幕截图,并指出了 URL 不同组成部分:协议、主机、路径、查询和 hash 

通常,URL 的任何更改都会导致加载新的页面。唯一的例外是 hash 值的变化。任何 URL 的 hash 更改都不会导致页面刷新。许多 Web 2.0 网站中都已经开始广泛使用 Hash,以标记部分刷新页面时的每一个步骤。在跨域通信中,hash 是一笔宝贵的资产。虽然在获取对方 hash 值方面有一些限制,但来自不同源点的文件可以设置对方的 URL,包括 hash 值。文档相互之间可以使用 hash 传送信息。图 3 显示了一个示例。


图 3. 使用 URL.hash(fragment id) 进行通信
具有不同 URL 的文档通过更改其他文档的 hash 值并监视自身 hash 的变化来进行通信的描述 

在图 3 中,当 A 想要向 B 发送信息时,它可以修改 B 的 hash 值,如清单 1 所示:


清单 1. 通过 url.hash 发送信息
function sendMsg(originURL, msg){var data = {from:originURL, msg:msg};var src = originURL + “#” + dojo.toJson(data);document.getElementById('domainB').src=src;}

B 中的函数将轮询自身的 hash 值,找出 A 发送的是什么,然后它可以用同样的方式回复 A。如果 A 想接收这条消息,也需要轮询其本身的 hash 值。


清单 2. 监视 url.hash 并从中接收信息
window.oldHash="";checkMessage = function(){var newHash = window.location.hash;if(newHash.length > 1){newHash = newHash.substring(1,newHash.length);if(newHash != oldHash){ oldHash = newHash; var msgs = dojo.fromJson(newHash); var origin = msgs.from; var msg = msgs.msg;  sendMessage(origin, "Hello document A");  } }}window.setInterval(checkMessage, 1000);sendMessage = function(target, msg){var hash = "msg="+ msg;parent.location.href= target + “#” + hash;}
(6)

HTML5 中的新功能

在 HTML5 规范的草案中,新方法 window.postMessage(message, targetOrigin) 可用于安全跨域通信。调用该方法时,会分派一个消息事件,如果该窗口正在监听消息事件,那么它能够从事件中获取消息以及消息来源。图 7 显示了一个示例。


图 7. 使用 HTML5 进行跨域通信
对使用 HTML5 中的固有功能 (window.postMessage) 和信息事件监听器进行跨域通信的描述 

在图 7 中,当 iframe 想要通知来自另一个源点的父窗口已成功完成加载时,它可以通过 window.postMessage 发送消息。同时,它将监测反馈消息,如清单 9 所示:


清单 9. 通过 HTML5 的新方法发送消息
http://www.otherapp.com/index.htmlfunction postMessage(msg){     var targetWindow = parent.window;      targetWindow.postMessage(msg,"*");}function handleReceive(msg){ var object = dojo.fromJson(msg); if(object.status == “ok”){//continue to do other things…… }else{//retry sending msg…… }}window.addEventListener("message", handleReceive, false);window.onLoad = function(){    postMessage("already loaded");}

父文档将监听消息事件。当消息到达时,会先检查它是否来自 www.otherapp.com,然后返回确认消息。


清单 10. 通过 HTML5 的新方法接收消息
http://www.myapp.com/index.htmlfunction handleReceive(event){     if(event.origin != "http://www.otherapp.com")        return;      //process data     ……     var otherAppFrame = document.getElementById(“otherApp”)      otherAppFrame.postMessage(“{status:’ok’}”,”http://www.otherapp.com”);}window.addEventListener("message", handleReceive, false);

清单 10 中的示例代码可以在 Firefox 3+、Internet Explorer 8、Google Chrome 2、Opera 9+ 以及 Safari 4 中运行。它使得来自不同来源的文档之间的通信变得更加方便。此外,如果不希望自己的文档收到来自其他文档的任何消息,那么不要添加事件监听器并删除所有消息。


像 JSONP 一样,这种方法也有一个长度限制,但它可以更好地处理错误。一些特殊字符,比如问号(?),是 URL 中的保留字符,应先对这些字符进行编码。


清单 3. 通过 url.hash 发送包含特殊符号的信息
function sendMsg(originURL, msg){…var src = originURL + “#” + encodeURI (dojo.toJson(data));…}

接收时,应先进行解码。


清单 4. Receiving message containing special characters
function checkMsg(){…var msgs = decodeURI(dojo.fromJson(newHash)); …}
还可用hash进行ajax的前进与后退的处理
原创粉丝点击