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'; //**
//创建了iframe
var 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,但其它的方法,在工作想项目中会被用到
工作中遇到问题,可以在课程里面找到解决方案,这是课程的初衷
解决方案,思路