iframe
<iframe src="./index2.html" id="myIframe"></iframe><script>var myIframe=document.getElementById("myIframe");myIframe.onload=function (){console.log(myIframe.contentWindow.name);}</script>
<script !src="">// window.name='iframeWindow';// name='iframeWindow';var name='iframeWindow';</script>
运行index结果如下

当index2被index的iframe元素加载时,可以认为index get得到的iframe有index2的window对象,iframe是一个窗口,iframe.contentWindow等价于index2的window窗口对象(窗口对象)。window.name,就相当于声明了一个变量。index2中的三句话是一个意思。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index</title></head><body><iframe src="./index2.html" id="myIframe"></iframe><script>var myIframe = document.getElementById("myIframe");window.name = 'mainWindow';myIframe.onload = function () {console.log(myIframe.contentWindow.name);}</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index2</title></head><body><iframe src="./index3.html" id="myIframe"></iframe><script !src="">window.name = 'iframeWindow';var iframe = document.getElementById('myIframe');iframe.onload = function () {console.log(window.parent.name)}</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index3</title></head><body></body></html>
index运行结果
index2运行结果
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index</title></head><body><iframe src="./index2.html" id="myIframe"></iframe><script>var myIframe = document.getElementById("myIframe");window.name = 'mainWindow';myIframe.onload = function () {console.log('index contentWindow',myIframe.contentWindow.name);}</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index2</title></head><body><iframe src="./index3.html" id="myIframe"></iframe><script !src="">window.name = 'iframeWindow';var iframe = document.getElementById('myIframe');iframe.onload = function () {console.log('index2 parent',window.parent.name)}</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index3</title></head><body><script !src="">console.log('index3 parent',window.parent.name)console.log('index3 parent.parent',window.parent.parent.name)</script></body></html>
index运行结果
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index</title></head><body><script>window.name = "window";location.href='index2.html';</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index2</title></head><body><script !src="">console.log('index',window.name);</script></body></html>

window.name有共享性的,换成name1就变成了undefined,即使不同页面也可以共享

<iframe src="http://test2.jsplusplus.com/transfer/index.html" id="myIframe"></iframe><script !src="">var myIframe=document.getElementById("myIframe");myIframe.onload=function (){console.log(myIframe.contentWindow.name);}</script>

跨域错误,主页面源不同,无法拿到window
跨域HTTP请求
跨域
源http://test2.jsplusolus.com/向源[http://test2.jsplusolus.com](http://test2.jsplusolus.com)获取资源
方法1 服务器中转请求

同源策略只针对客户端浏览器,服务器不受服务器影响
不一定只能客户端向服务器发请求,也可以服务器向服务器发请求
客户端请求同源服务器,同源服务器请求别的不同源的服务器,再由同源服务器把请求到的传给客户端
找同源的服务器,让它帮忙周转。就像找认识的人,让认识的人找别人,相当于中介
中转服务器程序
index
是test2.jsplusplus.com的源,想请求study.jsplusplus.com的源
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><script src="./utils.js"></script></head><body><script !src="">$.ajax({url:'http://study.jsplusplus.com/Index/getCourse',type : 'GET',success:function (data){console.log(data)}})</script></body></html>


<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><script src="./utils.js"></script></head><body><script !src="">$.ajax({// url:'http://study.jsplusplus.com/Index/getCourse',url:'http://test2.jsplusplus.com/transfer/server/api.php',type : 'GET',success:function (data){console.log(data)}})</script></body></html>
index请求同源的服务器,同源服务器请求别的服务器,得到数据,返回给同源的网页,客户端
2 设置基础域名+iframe

http://test2.jsplus.com/index.html
http://test.jsplus.com/index.html
都是jsplus.com一样,是基础域名一样
这种方式用的最多
原理
请求页面 http://test2.jsplus.com/index.html
在两个
请求页面,客户端页面
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>index</title></head><body><script !src="">//设置基础域名document.domain = 'jsplus.com'; //**//创建了iframevar iframe = document.createElement('iframe');// iframe 引入与接口同源的的页面 1.设置相同的基础域名//iframe引入不同源页面iframe.src = 'http://test.jsplus.com/index.html';iframe.id = 'myIframe';//设置为none,不让其显示,但是加载运行了,只是视觉效果看不到iframe.style.display = 'none';iframe.onload = function () {console.log(document.getElementById('myIframe').contentWindow);}document.body.appendChild(iframe);</script></body></html>

为什么有$对象,因为index2引入了utils.js文件,里面有封装的ajax方法,所以全局window会出现$对象
http://test2.jsplus.com/index.html的index通过iframe引入与他基础域名一致但不同源的http://test.jsplus.com/index.html的index2,都是jsplus.com的后缀名,通过得到index2页面的代码,ajax代码,请求http://test.jsplus.com/上的资源,请求同源资源
因为是用index2的页面的$ ajax对象请求的,ajax对象在’http://test.jsplus.com/index.html’ index2上,请求”http://test.jsplus.com/get_courses1.php“这两个同源,
利用同源网站上的ajax方法,请求同源网站
ajax请求不是index发出来的,是index2发出来的,是index调用index2的ajax发出来的,也算index2发出来的
iframe的src可以不同源请求,引入,但其基础域名必须一样
步骤
1当前页面设置基础域名
2想要请求跨域页面的api的源上面的某一个页面,设置同样的基础域名
3当前页面通过iframe引入上面设置的页面
//设置基础域名document.domain = 'jsplus.com'; //**var iframe = document.createElement('iframe');// iframe 引入与接口同源的的页面 1.设置相同的基础域名iframe.src = 'http://test.jsplus.com/index.html';iframe.id = 'myIframe';iframe.style.display = 'none';iframe.onload = function(){// 获取并使用iframe的ajax程序var $$ = document.getElementById('myIframe').contentWindows.$;$$.post('http://test.jsplus.com/get_courses1.php',{status:1,},function(data){console.log(data);});}document.body.appendChild(iframe);
被引入的请求页面 http://test.jsplus.com/index.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>index2</title></head><body></body><script src="./utils.js"></script><script>//设置基础域名document.domain = 'jsplus.com';</script></html>
window
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>index2</title></head><body></body><script src="./utils.js"></script><script>//设置基础域名// document.domain = 'jsplus.com';console.log(window)</script></html>
封装ajaxDomain函数
var ajaxDomain = (function () {//在返回的函数中被调用,参数被赋值function createIframe(frameId, frameUrl) {var frame = document.createElement('iframe');frame.scr = frameUrl;frame.id = frameId;frame.style.display = 'none';return frame;}return function (opt) {document.domain = opt.basicDomain;var frame = createIframe(opt.frameId, opt.frameUrl);frame.onload = function () {var $$ = document.getElementById(opt.frameId).contentWindows.$;$$.ajax({url: opt.url,type: opt.type,data: opt.data,success: opt.success,error: opt.error})}document.body.appendChild(frame);}})();console.log(window)ajaxDomain({basicDomain: 'jsplus.com',frameUrl: 'http://test.jsplus.com/index.html', //需要引入的请求的页面url: 'http://test.jsplus.com/get_courses1.php', //需要请求的接口type: 'POST',data: {status: 1},success: function (data) {console.log(data);},error: function () {console.log('error');}})8
跨域3 window.name+iframe



test2
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>demo1</title></head><body><script !src="">window.name = '我是DEMO1';setTimeout(function () {window.location = 'demo2.html'}, 1000)</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>demo2</title></head><body><script !src="">console.log(window.name);</script></body></html>
运行demo1结果
跳转到demo2,打印如下结果,说明name属性可以在两个页面共享,必须是name属性才可以共享,随便一个属性名不可以,name1属性不可以

父页面 有iframe元素的页面 (http://test2.jsplusplus.com/index.html)
var iframe=document.createElement("iframe");iframe.src="http://jsplusplus.com/index.html";iframe.onload=function (){console.log(iframe.contentWindow.name);}document.body.appendChild(iframe);
子页面 被iframe引用的页面(http://test.jsplusplus.com/index)
$.post('http://test.jsplusplus.com/get_courses.php',{status : 1},function (data){window.name=JSON.stringify(data);})

var flag=false;var iframe=document.createElement("iframe");var getDatas=function (){if(flag){var data=iframe.contentWindow.name;console.log(JSON.parse(data))}else {flag=true;// iframe.contentWindow.location='index2.html';setTimeout(function (){iframe.contentWindow.location='index2.html';},500)}}iframe.src="http://jsplusplus.com/index.html";iframe.onload=function (){console.log(iframe.contentWindow.name);}document.body.appendChild(iframe);if(iframe.attachEvent){iframe.attachEvent('onload',getDatas);}else {iframe.onload=getDatas;}document.body.appendChild(iframe);
flag一开始为false走
if(iframe.attachEvent){iframe.attachEvent('onload',getDatas);}else {iframe.onload=getDatas;}
走getDatas方法,flag:false,必然走下面的方法
var getDatas=function (){if(flag){var data=iframe.contentWindow.name;console.log(JSON.parse(data))}else {flag=true;// iframe.contentWindow.location='index2.html';setTimeout(function (){iframe.contentWindow.location='index2.html';},500)}}
跳转页面,iframe继续onload,flag:true,继续走getDatas方法,走上面的得到名字
分析
一开始
父页面 有iframe元素的页面 (http://test2.jsplusplus.com/index.html)
子页面 被iframe引用的页面(http://test.jsplusplus.com/index)
父页面引用子页面,它俩不同源,只是父页面得不到子页面的数据,但子页面可以运行,运行代码,子页面请求与其同源的资源,存到window.name中
$.post('http://test.jsplusplus.com/get_courses.php',{status : 1},function (data){window.name=JSON.stringify(data);})
把得到数据存到window.name中,但父页面不同源得不到数据,但数据在window.name中存着,是共享的
之后让iframe跳转到与子页面同源的一个页面,随便一个页面,从新的同源页面请求共享的window.name
开发用的太多了,多用几次就明白了
跨域4 postmessage+iframe

父页面 有iframe元素的页面 (http://test2.jsplusplus.com/index.html)
<iframe src="http://test.jsplusplus/index.html" id="iframe"></iframe><script src="./utils.js"></script><script !src="">//监听window.onmessage=function(e) {var e=e||window.event;console.log(JSON.parse(e.data));}</script>
子页面 被iframe引用的页面(http://test.jsplusplus.com/index)
<script src="./utils.js"></script><script !src="">$.post('http://test.jsplusplus/get_courses.php',{status : 1},function (data){window.name=JSON.stringify(data);window.parent.postMessage(JSON.stringify(data),'http://test2.jsplusplus.com')})</script>
父页面引用子页面,子页面代码执行,请求子页面同源的资源,发给父页面,父页面监听
总结
跨域5 hash+iframe
基本原理:利用url得hash值 #xxx来传递数据
基础工具:location.hash

<a href="#red">红色</a><a href="#green">绿色</a><a href="#blue">蓝色</a><a href="#yellow">黄色</a><botton id="btn">获取HASH</botton><script !src="">console.log(location.hash)var oBtn=document.getElementById("btn");oBtn.onclick=function (){console.log(location.hash)}</script>


点击按钮,获取yellow
父级页面 parent.html (http://test2.jsplusplus.com/hash/index.html)
<iframe src="http://test.jsplusplus/index.html#getCourses" id="iframe"></iframe>var oBtn = document.getElementById('btn');oBnt.onclick = function(){console.log(JSON.parse(decodeURI(location.hash.substring(1))));}
子级页面:son.html (http://test.jsplusplus.com/index.html)
<iframe src="http://test2.jsplusplus.com/hash/index2.html" frameborder="0" id="iframe"></iframe><script src="./utils.js"></script><script !src="">var hash=location.hash.substring(1),iframe=document.getElementById('iframe');switch (hash) {case "getCourses":$.post('http://test.jsplusplus.com/get_courses.php',{status : 1},function (data){var str=JSON.stringify(data);iframe.src="http://test2.jsplusplus.com/hash/index2.html#"+str;})}</script>
孙级页面:son2.html (http://test2.jsplusplus.com/hash/index2.html)
<script !src="">setTimeout(function() {parent.parent.location.hash=self.location.hash.substring(1)},300)</script>
解析
还是父级页面加载son子级页面,son页面程序都会加载,可以拿到(http://test.jsplusplus/index.html#getCourses)#getCourses,就可以在son里面进行ajax请求,son的iframe设置为与parent同源的页面,因为parent与孙级页面同源,所以可以更改hash,把孙级页面的hash给父级页面
传简单值可以,复杂值不可以
思路
parent(http://test2.jsplusplus.com/hash/index.html)想请求(http://test.jsplusplus.com/get_courses.php)api获取资源,跨域无法请求,用iframe引入son (http://test.jsplusplus.com/index.html)网页,son请求(http://test.jsplusplus.com/get_courses.php)同源,son不能修改parent的hash,因为不同源,iframe设置与parent同源的src,并把hash传过去,孙级元素son2接收hash给同源的parent,因为ajax耗时,所以延迟300ms,如果不延迟吗,立即触发,可能son2没有得到hash,就直接给父元素传过去了,可以hash为空,或者hash没有传全

点击取消链接
跨域6 cors跨域


任何域都可以跨,服务器设置跨域,不同语言设置不一样
一般机构只讲jsonp,但其它的方法,在工作想项目中会被用到
工作中遇到问题,可以在课程里面找到解决方案,这是课程的初衷
解决方案,思路

