跨域问题

(一)跨域发起请求

1. JSONP

JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。

JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好

JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

2. CORS

CORS(Cross-Origin Resource Sharing)跨域资源共享

服务器端对于CORS的支持,主要就是通过设置响应头的Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

// 指定允许其他域名访问  
header('Access-Control-Allow-Origin:*');  
// 响应类型  
header('Access-Control-Allow-Methods:POST');  
// 响应头设置  
header('Access-Control-Allow-Headers:x-requested-with,content-type');  

(二)跨域js访问

浏览器都有一个同源策略,其限制之一就是第一种方法中我们说的不能通过ajax的方法去请求不同源中的文档。 它的第二个限制是浏览器中不同域的框架之间是不能进行js的交互操作的。

不同的框架之间是可以获取window对象的,但却无法获取相应的属性和方法。比如,有一个页面,它的地址是http://www.example.com/a.html , 在这个页面里面有一个iframe,它的src是http://example.com/b.html, 很显然,这个页面与它里面的iframe框架是不同域的,所以我们是无法通过在页面中书写js代码来获取iframe中的东西的

<script type="text/javascript">
    function test(){
        var iframe = document.getElementById('ifame');
        var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的
        var doc = win.document;//这里获取不到iframe里的document对象
        var name = win.name;//这里同样获取不到window对象的name属性
    }
</script>

1. 同一主域情况下设置document.domain

我们只要把http://www.example.com/a.html 和 http://example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。

2. postMessage

HTML5 提供了在网页文档之间互相接收与发送信息的功能。使用这个功能,只要获取到网页所在窗口对象的实例,不仅同源(域 + 端口号)的 Web 网页之间可以互相通信,甚至可以实现跨域通信。 要想接收从其他窗口发送来的信息,必须对窗口对象的 onmessage 事件进行监听,其它窗口可以通过 postMessage 方法来传递数据。该方法使用两个参数:第一个参数为所发送的消息文本,但也可以是任何 JavaScript 对象(通过 JSON 转换对象为文本),第二个参数为接收消息的对象窗口的 URL 地址,可以在 URL 地址字符串中使用通配符'*'指定全部地。

 <script type="text/JavaScript"> 
     function sendIt(){ 
         // 通过 postMessage 向子窗口发送数据
         document.getElementById("otherPage").contentWindow 
             .postMessage( 
                 document.getElementById("message").value, 
                "http://child.com:8080"
             ); 
     } 
 </script> 
 </head> 
 <body> 
     <!-- 通过 iframe 嵌入子页面 --> 
     <iframe src="http://child.com:8080/TestHTML5/other-domain.html" 
                 id="otherPage"></iframe> 
     <br/><br/> 
     <input type="text" id="message"><input type="button" 
             value="Send to child.com" onclick="sendIt()" /> 
 </body>
//event 参数中有 data 属性,就是父窗口发送过来的数据
     window.addEventListener("message", function( event ) { 
         // 把父窗口发送过来的数据显示在子窗口中
       console.log(event.data); 
     }, false ); 

  

原文地址:https://www.cnblogs.com/webLilingyun/p/7218819.html