前端跨域记录

一、跨域定义及类型

定义:只要协议、域名、端口有任何一个不同,都被当做不同的域。

类型:(由于浏览器的同源策略)

1)浏览器中不同域的框架之间不能进行js交互操作;

2)不能通过ajax去请求不同源中的文档;

注意:由于协议和端口造成的跨域,前端无法解决。

跨域处理:

1、document.domain

用于处于跨域的第一种类型,iframe类型。

例子:

A页面:http://www.baidu.com/a.html

B页面:http://www.google.com/b.html(作为iframe页面嵌入到A页面中)

A页面中:

var iframe = document.getElementById('iframe');
var win = iframe.contentWindow;
var doc = win.document;
console.log(doc); //报错

结论:A页面可以得到B页面的window对象,但无法获取window对象的属性和方法;

使用document.domain设置两个页面的主域相同。(注意:主域只能设置为自身或者更高一级的父域)

A页面设置document.domain = ‘baidu.com’;B页面设置document.domain = ‘baidu.com’;

这样便可以进行父子域的js交互。

2.location.hash

父窗口可以读写iframe的url,子窗口也可以读写父窗口的url(俩页面在不同域下IE、chrome不允许修改parent.location.hash),hash是跟随在url后面的#及其后面的内容,一般用作浏览器锚点定位。虽然hash不参与http请求,但会产生浏览器记录。

可以通过hash传参。

A页面为父页面(http://www.baidu.com/a.html),B页面为子页面( http://www.google.com/b.html),两者的域不同,要兼容IE、chrome的无法获取IE、chrome的无法获取parent.location.hash的情况,代码如下:

try{
  parent.location.hash = 'data';  
}catch(e){
  var Iframe = document.createElement('iframe');
  Iframe.style.display = 'none';
  Iframe.src =  'http://www.baidu.com/proxy.html#data';//子Iframe的域需要与A页面相同
  document.body.appendChild(Iframe);  
} 

proxy.html页面的设置:

parent.parent.location.hash= self.location.hash.substring(1);

 

3.通过postMessage跨域

A页面(baidu.com),B页面(google.com);

A页面代码:

<script>
    var  iframe = document.getElelmentById('iframe');
    var targetOrigin = 'www.google.com';//接受着的范围
    iframe.contentWindow.postMessage('Hello World', targetOrigin);
</script>

postMessage方法的API:otherWindow.postMessage(messageBody, targetOrigin);

  otherWindow:其他窗口;

  messageBody:消息主体;

  targetOrigin:接受者的范围;

 B页面获取方法:

function onMessage (event) {
  var data = event.data;//消息
  var origin = event.orgin;//发送源的地址
  var source = event.source;  //发送源的window对象
  if(origin == 'http://www.baidu.com'){
      //doing something
  }
}

if(typeof window.addEventListener != 'undefined') {
    window.addEventListener('message', onMessage, false);
}else if(typeof window.attachEvent != 'undefined') {
   window.attachEvent('onmessage', onMessage);
}

  

4、通过jsonp跨域

原理:script标签引用资源不受浏览器同源策略的限制。script的src属性可以访问跨域的js脚本,因此服务器不再返回json数据,而是返回一段调用某函数的js代码,在src进行了调用。

对象:不针对不同域的iframe页面通信,而是希望从服务端获取数据。

例子:A页面(a.html)需要通过ajax获取一个不同域上的json数据。假设json数据的地址为http://www.yoriluo.top/data.php,则a.html的代码如下:

<script>
    function doSomething(jsondata) {
       ...
    }
</script>
<script src="http://www.yoriluo.top/data.php?callback=doSomething"></script>

其中http://www.yoriluo.top/data.php页面一定是返回可执行的js文件,需要与后端商量好。

jsonp只支持GET请求,只支持HTTP请求。

5.CROS跨域(未深入)

 使用方法:与ajax相同

普通ajax:

function ajax(){
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'api/...’, true); 本地域的资源地址
  xhr.send();
}

  使用CROS:

function ajax(){
  var xhr = new XMLHttpRequest();
  xhr.open('GET', '‘http://segmentfault.com/u/trigkit4/’, true); //地址为你想跨域访问资源的地址
  xhr.send();
}

  CROS跨域需要与服务端协商好,需在服务端设置 Access-Control-Allow-Origin;

6.window.name跨域(未深入)

使用父窗口与frame窗口的window.name的值相同,但不支持不同源的共享。

原文地址:https://www.cnblogs.com/Yoriluo/p/7508345.html