属性仅对相同域名的 frame 可访问

作者:betway计算机知识

在客户端编制程序语言中如javascript,同源计策规定跨域之间的脚本是割裂的,三个域的本子不可能访谈和操作其它叁个域的绝超过八分之四性质和情势。唯有当三个域具有同等的情商,相同的主机,同样的端口时,我们就确定他们是平等的域。可是在实际成本中大家平常须要获得别的域的财富,那一年各样分歧的跨域财富格局就各显神通了,后日主要来总括一下行事中常用的三种跨域形式,以备查询。

1.window.name

window 对象的name属性是一个很极其的质量,当在 frame 中加载新页面时,name 的属性值还是保持不改变。那么我们得以在页面 A中用iframe加载别的域的页面B,而页面B中用JavaScript把必要传递的数额赋值给window.name,iframe加载完结之后,此时 name 属性值可被拿走到,以访谈 Web 服务发送的新闻。但 name 属性仅对同一域名的 frame 可访谈。那意味为了访谈 name 属性,当远程 Web 服务页面被加载后,必须导航 frame 回到原始域。即页面A修改iframe的地址,将其成为同域的一个地点,然后就能够读出window.name的值了。一旦 name 属性获得,销毁 frame 。那么些办法非常适合单向的多少央浼,并且协议轻巧、安全。

页面B(www.jesse.com/data.html)代码如下:

<script type="text/javascript">
window.name = 'I was there!';
// 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右
// 数据格式可以自定义,如json、字符串
</script>

页面A(www.jack.com/index.html)代码如下:

<script type="text/javascript">
var state = 0,
  iframe = document.createElement('iframe'),
  loadfn = function() {
    if (state === 1) {
      var data = iframe.contentWindow.name; // 读取数据
      console.log(data); //弹出'I wasthere!'
      (function(){
        //获取数据以后销毁这个iframe。
        iframe.contentWindow.document.write('');
        iframe.contentWindow.close();
        document.body.removeChild(iframe);
      })();
    } else if (state === 0) {
      state = 1;
      // 设置的代理页面使其回原始域
      iframe.contentWindow.location = "http://www.jack.com/proxy.html"; 
    }
  };
iframe.src = 'http://www.jesse.com/data.html';
if (iframe.attachEvent) {
  iframe.attachEvent('onload', loadfn);
} else {
  iframe.onload = loadfn;
}
document.body.appendChild(iframe);
</script>

2.具备src的标签

即使浏览器暗许禁止了跨域访谈,但并不禁止在页面中用竹签的src属性援引其余域的文本。依照那一点,能够一本万利地通过创造具备src属性的节点方法来贯彻完全跨域的通讯。使用这种规律的跨域格局有以下两种:

动态创造script

例如说小编要从域A的页面pageA加载域B的数码,那么在域B的页面pageB中自己以JavaScript的花样申明pageA需求的多少,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就能够得以试行。

pageA(www.jack.com/index.html)代码如下:

function getData(data){
  //这里是对获取的数据的相关操作
  console.log(data);
  //数据获取到后移除创建的script标签
  document.body.removeChild(originData);
}
var originData = document.createElement('script');
originData.src = 'http://www.jesse.com/data.js';
originData.setAttribute("type", "text/javascript");
document.body.appendChild(originData);

pageB(www.jesse.com/data.js)代码如下:

getData('这里是远程跨域获取的数据');//数据格式可以自定义,如json、字符串

jsonp

在用$.ajax()获取远程数据时,若是是跨域资源则能够利用jsonp方法,在此以前平昔感觉jsonp是ajax的一种,后来才晓得他们一向就不是二次事。ajax是以xhr形式诉求数据的,而jsonp是以script格局呼吁数据的,这几个正是和方面包车型地铁动态创立script方式一样。

pageA(www.jack.com/index.html)代码如下:

$.ajax({
  //JSONP不支持POST方式
  type:"GET",
  url:"http://www.jesse.com/data.php",
  dataType:"jsonp",
  //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
  jsonpCallback:"getData",
  success: function(data){
    console.log(data);
  },
  error: function(){
    console.log('fail');
  }
})

pageB(www.jesse.com/data.js)代码如下:

<?php
  $callback = $_GET['callback'];//得到回调函数名,这里是getData
  $data = array('a','b','c');//要返回的数据
  echo $callback.'('.json_encode($data).')';//输出
?>

3.document.domain

对此主域同样而子域差异的例子,能够通过设置document.domain的主意来缓慢解决。 具体的做法是能够在 document.domain = "a.com";然后通过a.html文件中开创二个iframe,去调控iframe的contentDocument,那样八个js文件之间就能够“交互”了。当然这种艺术只可以一挥而就主域一样而二级域名差异的景象

www.a.com上的a.html

document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
  var doc = ifr.contentDocument || ifr.contentWindow.document;
  // 在这里操纵b.html
  alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

script.a.com上的b.html

document.domain = 'a.com';

4.跨域财富分享(CO奥德赛S)

规律:跨源财富分享(COEnclaveS)定义一种跨域访问的建制,能够让AJAX完结跨域访谈。CO中华VS允许二个域上的互连网使用向另八个域交到跨域AJAX需要。实现此意义非常轻松,只需由服务器发送叁个响应标头就能够。它是经过客户端 服务端合作评释的章程来有限支撑央浼安全的。服务端会在HTTP须要头中扩大一雨后苦笋HTTP供给参数(比如Access-Control-Allow-Origin等),来界定哪些域的乞求和什么央求类型还不错,而客户端在倡议呼吁时务必阐明本人的源(Orgin),不然服务器将反对处理,借使客户端不作申明,乞请以至会被浏览器直接堵住都到不断服务端。服务端收到HTTP央求后会实行域的可比,唯有同域的央求才会管理。

pageA(www.jack.com/index.html)代码如下:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
  if(xhr.readyState === 4 && xhr.status === 200){
    console.log(xhr.responseText);
  }
};
xhr.open("get","http://www.jesse.com/data.php");
xhr.send(null);

pageB(www.jesse.com/data.php)代码如下:

<?php
  header("Access-Control-Allow-Origin: http://www.jack.com");//与简单的请求相同
  header("Access-Control-Allow-Methods: GET, POST");//允许请求的方法
  header("Access-Control-Max-Age: 3628800"); //将这个请求缓存多长时间
  $data = array('a','b','c');//要返回的数据
  echo json_encode($data);//输出
?>

5.window.postMesage 不常用

window.postMessage(message,targetOrigin) 方法是html5新引入的特征,能够选拔它来向其余的window对象发送消息,无论这些window对象是属于同源或分裂源,近些日子IE8 、FireFox、Chrome、Opera等浏览器都曾经援助window.postMessage方法。

pageA(www.jack.com/index.html)代码如下:

<iframe id="proxy" src="http://www.jesse.com/index.html" onload="postMsg()" style="display: none"></iframe>
<script type="text/javascript">
var obj = {
  msg: 'hello world'
}

function postMsg() {
  var iframe = document.getElementById('proxy');
  var win = iframe.contentWindow;
  win.postMessage(obj, 'http://www.jesse.com');
}
</script>

pageB(www.jesse.com/data.php)代码如下:
<script type="text/javascript">
window.onmessage = function(e) {
  console.log(e.data.msg   " from "   e.origin);
}
</script>

6. location.hash 不常用

pageA(www.jack.com/index.html)代码如下:

function startRequest() {
  var ifr = document.createElement('iframe');
  ifr.style.display = 'none';
  ifr.src = 'http://www.jesse.com/b.html#sayHi'; //传递的location.hash 
  document.body.appendChild(ifr);
}

function checkHash() {
  try {
    var data = location.hash ? location.hash.substring(1) : '';
    if (console.log) {
      console.log('Now the data is '   data);
    }
  } catch (e) {};
}
setInterval(checkHash, 5000);
window.onload = startRequest;

pageA(www.jack.com/proxy.html)代码如下:

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

pageB(www.jesse.com/b.html)代码如下:

function checkHash() {
  var data = '';
  //模拟一个简单的参数处理操作
  switch (location.hash) {
    case '#sayHello':
      data = 'HelloWorld';
      break;
    case '#sayHi':
      data = 'HiWorld';
      break;
    default:
      break;
  }
  data && callBack('#'   data);
}

function callBack(hash) {
  // ie、chrome的安全机制无法修改parent.location.hash,所以要利用一个中间的www.a.com域下的代理iframe
  var proxy = document.createElement('iframe');
  proxy.style.display = 'none';
  proxy.src = 'http://www.jack/c.html'   hash; // 注意该文件在"www.jack.com"域下
  document.body.appendChild(proxy);
}
window.onload = checkHash;

以上正是本文的全体内容,希望对大家的上学抱有协理,也愿意大家多多帮忙脚本之家。

您恐怕感兴趣的作品:

  • jsonp跨域央浼详解
  • angular.js中国化学工业进出口总公司解跨域难题的二种方法
  • nodeJS(express4.x) vue(vue-cli)营造前后端分离实例(带跨域)
  • jQuery Jsonp跨域模拟搜索引擎
  • 详解Java Ajax jsonp 跨域诉求
  • 详解VueJs前后端分离跨域难点
  • 详解Vuejs2.0之异步跨域伏乞
  • JSONP跨域乞求
  • javascript 跨域难点以及消除办法

本文由betway-必威手机用户端-必威注册发布,转载请注明来源

关键词: 必威中文官网