iframe

  1. <iframe src="./index2.html" id="myIframe"></iframe>
  2. <script>
  3. var myIframe=document.getElementById("myIframe");
  4. myIframe.onload=function (){
  5. console.log(myIframe.contentWindow.name);
  6. }
  7. </script>
  1. <script !src="">
  2. // window.name='iframeWindow';
  3. // name='iframeWindow';
  4. var name='iframeWindow';
  5. </script>

运行index结果如下
image.png
image.png
当index2被index的iframe元素加载时,可以认为index get得到的iframe有index2的window对象,iframe是一个窗口,iframe.contentWindow等价于index2的window窗口对象(窗口对象)。window.name,就相当于声明了一个变量。index2中的三句话是一个意思。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index</title>
  6. </head>
  7. <body>
  8. <iframe src="./index2.html" id="myIframe"></iframe>
  9. <script>
  10. var myIframe = document.getElementById("myIframe");
  11. window.name = 'mainWindow';
  12. myIframe.onload = function () {
  13. console.log(myIframe.contentWindow.name);
  14. }
  15. </script>
  16. </body>
  17. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index2</title>
  6. </head>
  7. <body>
  8. <iframe src="./index3.html" id="myIframe"></iframe>
  9. <script !src="">
  10. window.name = 'iframeWindow';
  11. var iframe = document.getElementById('myIframe');
  12. iframe.onload = function () {
  13. console.log(window.parent.name)
  14. }
  15. </script>
  16. </body>
  17. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index3</title>
  6. </head>
  7. <body>
  8. </body>
  9. </html>

index运行结果
image.png
index2运行结果
image.png

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index</title>
  6. </head>
  7. <body>
  8. <iframe src="./index2.html" id="myIframe"></iframe>
  9. <script>
  10. var myIframe = document.getElementById("myIframe");
  11. window.name = 'mainWindow';
  12. myIframe.onload = function () {
  13. console.log('index contentWindow',myIframe.contentWindow.name);
  14. }
  15. </script>
  16. </body>
  17. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index2</title>
  6. </head>
  7. <body>
  8. <iframe src="./index3.html" id="myIframe"></iframe>
  9. <script !src="">
  10. window.name = 'iframeWindow';
  11. var iframe = document.getElementById('myIframe');
  12. iframe.onload = function () {
  13. console.log('index2 parent',window.parent.name)
  14. }
  15. </script>
  16. </body>
  17. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index3</title>
  6. </head>
  7. <body>
  8. <script !src="">
  9. console.log('index3 parent',window.parent.name)
  10. console.log('index3 parent.parent',window.parent.parent.name)
  11. </script>
  12. </body>
  13. </html>

index运行结果
image.png

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index</title>
  6. </head>
  7. <body>
  8. <script>
  9. window.name = "window";
  10. location.href='index2.html';
  11. </script>
  12. </body>
  13. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index2</title>
  6. </head>
  7. <body>
  8. <script !src="">
  9. console.log('index',window.name);
  10. </script>
  11. </body>
  12. </html>

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

image.png

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

image.png
跨域错误,主页面源不同,无法拿到window

跨域HTTP请求

跨域
http://test2.jsplusolus.com/向源[http://test2.jsplusolus.com](http://test2.jsplusolus.com)获取资源

6种跨域方法

方法1 服务器中转请求

image.png
同源策略只针对客户端浏览器,服务器不受服务器影响
不一定只能客户端向服务器发请求,也可以服务器向服务器发请求
客户端请求同源服务器,同源服务器请求别的不同源的服务器,再由同源服务器把请求到的传给客户端

找同源的服务器,让它帮忙周转。就像找认识的人,让认识的人找别人,相当于中介

中转服务器程序
image.png

index
是test2.jsplusplus.com的源,想请求study.jsplusplus.com的源
image.png

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script src="./utils.js"></script>
  7. </head>
  8. <body>
  9. <script !src="">
  10. $.ajax({
  11. url:'http://study.jsplusplus.com/Index/getCourse',
  12. type : 'GET',
  13. success:function (data){
  14. console.log(data)
  15. }
  16. })
  17. </script>
  18. </body>
  19. </html>

image.png

image.png

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script src="./utils.js"></script>
  7. </head>
  8. <body>
  9. <script !src="">
  10. $.ajax({
  11. // url:'http://study.jsplusplus.com/Index/getCourse',
  12. url:'http://test2.jsplusplus.com/transfer/server/api.php',
  13. type : 'GET',
  14. success:function (data){
  15. console.log(data)
  16. }
  17. })
  18. </script>
  19. </body>
  20. </html>

index请求同源的服务器,同源服务器请求别的服务器,得到数据,返回给同源的网页,客户端

2 设置基础域名+iframe

image.png
http://test2.jsplus.com/index.html
http://test.jsplus.com/index.html
都是jsplus.com一样,是基础域名一样
这种方式用的最多

原理
请求页面 http://test2.jsplus.com/index.html

在两个
请求页面,客户端页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index</title>
  6. </head>
  7. <body>
  8. <script !src="">
  9. //设置基础域名
  10. document.domain = 'jsplus.com'; //**
  11. //创建了iframe
  12. var iframe = document.createElement('iframe');
  13. // iframe 引入与接口同源的的页面 1.设置相同的基础域名
  14. //iframe引入不同源页面
  15. iframe.src = 'http://test.jsplus.com/index.html';
  16. iframe.id = 'myIframe';
  17. //设置为none,不让其显示,但是加载运行了,只是视觉效果看不到
  18. iframe.style.display = 'none';
  19. iframe.onload = function () {
  20. console.log(document.getElementById('myIframe').contentWindow);
  21. }
  22. document.body.appendChild(iframe);
  23. </script>
  24. </body>
  25. </html>

image.png
为什么有$对象,因为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引入上面设置的页面

  1. //设置基础域名
  2. document.domain = 'jsplus.com'; //**
  3. var iframe = document.createElement('iframe');
  4. // iframe 引入与接口同源的的页面 1.设置相同的基础域名
  5. iframe.src = 'http://test.jsplus.com/index.html';
  6. iframe.id = 'myIframe';
  7. iframe.style.display = 'none';
  8. iframe.onload = function(){
  9. // 获取并使用iframe的ajax程序
  10. var $$ = document.getElementById('myIframe').contentWindows.$;
  11. $$.post('http://test.jsplus.com/get_courses1.php',{
  12. status:1,
  13. },function(data){
  14. console.log(data);
  15. });
  16. }
  17. document.body.appendChild(iframe);

被引入的请求页面 http://test.jsplus.com/index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>index2</title>
  8. </head>
  9. <body>
  10. </body>
  11. <script src="./utils.js"></script>
  12. <script>
  13. //设置基础域名
  14. document.domain = 'jsplus.com';
  15. </script>
  16. </html>

window

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>index2</title>
  8. </head>
  9. <body>
  10. </body>
  11. <script src="./utils.js"></script>
  12. <script>
  13. //设置基础域名
  14. // document.domain = 'jsplus.com';
  15. console.log(window)
  16. </script>
  17. </html>

image.png

被引入的代码会加载到window上面

封装ajaxDomain函数

  1. var ajaxDomain = (function () {
  2. //在返回的函数中被调用,参数被赋值
  3. function createIframe(frameId, frameUrl) {
  4. var frame = document.createElement('iframe');
  5. frame.scr = frameUrl;
  6. frame.id = frameId;
  7. frame.style.display = 'none';
  8. return frame;
  9. }
  10. return function (opt) {
  11. document.domain = opt.basicDomain;
  12. var frame = createIframe(opt.frameId, opt.frameUrl);
  13. frame.onload = function () {
  14. var $$ = document.getElementById(opt.frameId).contentWindows.$;
  15. $$.ajax({
  16. url: opt.url,
  17. type: opt.type,
  18. data: opt.data,
  19. success: opt.success,
  20. error: opt.error
  21. })
  22. }
  23. document.body.appendChild(frame);
  24. }
  25. })();
  26. console.log(window)
  27. ajaxDomain({
  28. basicDomain: 'jsplus.com',
  29. frameUrl: 'http://test.jsplus.com/index.html', //需要引入的请求的页面
  30. url: 'http://test.jsplus.com/get_courses1.php', //需要请求的接口
  31. type: 'POST',
  32. data: {
  33. status: 1
  34. },
  35. success: function (data) {
  36. console.log(data);
  37. },
  38. error: function () {
  39. console.log('error');
  40. }
  41. })8

跨域3 window.name+iframe

image.png

image.png
image.png

test2

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport"
  6. content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8. <title>demo1</title>
  9. </head>
  10. <body>
  11. <script !src="">
  12. window.name = '我是DEMO1';
  13. setTimeout(function () {
  14. window.location = 'demo2.html'
  15. }, 1000)
  16. </script>
  17. </body>
  18. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>demo2</title>
  6. </head>
  7. <body>
  8. <script !src="">
  9. console.log(window.name);
  10. </script>
  11. </body>
  12. </html>

运行demo1结果

跳转到demo2,打印如下结果,说明name属性可以在两个页面共享,必须是name属性才可以共享,随便一个属性名不可以,name1属性不可以
image.png
image.png

父页面 有iframe元素的页面 (http://test2.jsplusplus.com/index.html)

  1. var iframe=document.createElement("iframe");
  2. iframe.src="http://jsplusplus.com/index.html";
  3. iframe.onload=function (){
  4. console.log(iframe.contentWindow.name);
  5. }
  6. document.body.appendChild(iframe);

子页面 被iframe引用的页面(http://test.jsplusplus.com/index)

  1. $.post('http://test.jsplusplus.com/get_courses.php',{
  2. status : 1
  3. },function (data){
  4. window.name=JSON.stringify(data);
  5. })

image.png

  1. var flag=false;
  2. var iframe=document.createElement("iframe");
  3. var getDatas=function (){
  4. if(flag){
  5. var data=iframe.contentWindow.name;
  6. console.log(JSON.parse(data))
  7. }else {
  8. flag=true;
  9. // iframe.contentWindow.location='index2.html';
  10. setTimeout(function (){
  11. iframe.contentWindow.location='index2.html';
  12. },500)
  13. }
  14. }
  15. iframe.src="http://jsplusplus.com/index.html";
  16. iframe.onload=function (){
  17. console.log(iframe.contentWindow.name);
  18. }
  19. document.body.appendChild(iframe);
  20. if(iframe.attachEvent){
  21. iframe.attachEvent('onload',getDatas);
  22. }else {
  23. iframe.onload=getDatas;
  24. }
  25. document.body.appendChild(iframe);

flag一开始为false走

  1. if(iframe.attachEvent){
  2. iframe.attachEvent('onload',getDatas);
  3. }else {
  4. iframe.onload=getDatas;
  5. }

走getDatas方法,flag:false,必然走下面的方法

  1. var getDatas=function (){
  2. if(flag){
  3. var data=iframe.contentWindow.name;
  4. console.log(JSON.parse(data))
  5. }else {
  6. flag=true;
  7. // iframe.contentWindow.location='index2.html';
  8. setTimeout(function (){
  9. iframe.contentWindow.location='index2.html';
  10. },500)
  11. }
  12. }

跳转页面,iframe继续onload,flag:true,继续走getDatas方法,走上面的得到名字

分析

一开始

父页面 有iframe元素的页面 (http://test2.jsplusplus.com/index.html)
子页面 被iframe引用的页面(http://test.jsplusplus.com/index)

父页面引用子页面,它俩不同源,只是父页面得不到子页面的数据,但子页面可以运行,运行代码,子页面请求与其同源的资源,存到window.name中

  1. $.post('http://test.jsplusplus.com/get_courses.php',{
  2. status : 1
  3. },function (data){
  4. window.name=JSON.stringify(data);
  5. })

把得到数据存到window.name中,但父页面不同源得不到数据,但数据在window.name中存着,是共享的

之后让iframe跳转到与子页面同源的一个页面,随便一个页面,从新的同源页面请求共享的window.name

开发用的太多了,多用几次就明白了

跨域4 postmessage+iframe

image.png

父页面 有iframe元素的页面 (http://test2.jsplusplus.com/index.html)

  1. <iframe src="http://test.jsplusplus/index.html" id="iframe"></iframe>
  2. <script src="./utils.js"></script>
  3. <script !src="">
  4. //监听
  5. window.onmessage=function(e) {
  6. var e=e||window.event;
  7. console.log(JSON.parse(e.data));
  8. }
  9. </script>

子页面 被iframe引用的页面(http://test.jsplusplus.com/index)

  1. <script src="./utils.js"></script>
  2. <script !src="">
  3. $.post('http://test.jsplusplus/get_courses.php',{
  4. status : 1
  5. },function (data){
  6. window.name=JSON.stringify(data);
  7. window.parent.postMessage(JSON.stringify(data),'http://test2.jsplusplus.com')
  8. })
  9. </script>

父页面引用子页面,子页面代码执行,请求子页面同源的资源,发给父页面,父页面监听

总结

都是引入页面请求同源资源,再父页面想办法得到

跨域5 hash+iframe

基本原理:利用url得hash值 #xxx来传递数据
基础工具:location.hash

image.png

  1. <a href="#red">红色</a>
  2. <a href="#green">绿色</a>
  3. <a href="#blue">蓝色</a>
  4. <a href="#yellow">黄色</a>
  5. <botton id="btn">获取HASH</botton>
  6. <script !src="">
  7. console.log(location.hash)
  8. var oBtn=document.getElementById("btn");
  9. oBtn.onclick=function (){
  10. console.log(location.hash)
  11. }
  12. </script>

image.png

image.png
点击按钮,获取yellow

父级页面 parent.html (http://test2.jsplusplus.com/hash/index.html)

  1. <iframe src="http://test.jsplusplus/index.html#getCourses" id="iframe"></iframe>
  2. var oBtn = document.getElementById('btn');
  3. oBnt.onclick = function(){
  4. console.log(JSON.parse(decodeURI(location.hash.substring(1))));
  5. }

子级页面:son.html (http://test.jsplusplus.com/index.html)

  1. <iframe src="http://test2.jsplusplus.com/hash/index2.html" frameborder="0" id="iframe"></iframe>
  2. <script src="./utils.js"></script>
  3. <script !src="">
  4. var hash=location.hash.substring(1),
  5. iframe=document.getElementById('iframe');
  6. switch (hash) {
  7. case "getCourses":
  8. $.post('http://test.jsplusplus.com/get_courses.php',{
  9. status : 1
  10. },function (data){
  11. var str=JSON.stringify(data);
  12. iframe.src="http://test2.jsplusplus.com/hash/index2.html#"+str;
  13. })
  14. }
  15. </script>

孙级页面:son2.html (http://test2.jsplusplus.com/hash/index2.html)

  1. <script !src="">
  2. setTimeout(function() {
  3. parent.parent.location.hash=self.location.hash.substring(1)
  4. },300)
  5. </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没有传全

image.png
点击取消链接

跨域6 cors跨域

image.png

image.png
任何域都可以跨,服务器设置跨域,不同语言设置不一样

一般机构只讲jsonp,但其它的方法,在工作想项目中会被用到
工作中遇到问题,可以在课程里面找到解决方案,这是课程的初衷
解决方案,思路