JS跨域:window.postMessage + window.name +jsonp

1.window.postMessage

(1)在发送数据窗口执行:otherWindow.postMessage(msg,targetOrigin)

  • otherWindow:表示接受数据的窗口的window对象,包括iframe的contentWindwohe和通过window.open打开的新窗口。
  • msg表示要发送的数据,包扩字符串和对象(ie9以下不支持,可以利用字符串和json互换)
  • origin表示接收的域名。
(2)在接受的窗口监听window的message事件,回掉函数参数接受一个事件对象event,包括的属性有:

  • data:接受的数据
  • origin:发送端的域
  • source:发送端的DOMWindow对象
  • 例子
  • 1.在父框架页面index.html发送obj对象给远程服务器的wozien.com/test/b.html,该页面是通过iframe加载的,如下
  • [html]  view plain  copy
    1. >  
    2. <html>  
    3. <head>  
    4.     <title>window.postMessagetitle>  
    5.       
    6. head>  
    7. <body>  
    8.     <iframe id="proxy" src="http://wozien.com/test/b.html" onload = "postMsg()" style="display: none" >iframe>  
    9.   
    10.     <script type="text/javascript">  
    11.         var obj = {  
    12.             msg: 'this is come from client message!'  
    13.         }  
    14.   
    15.         function postMsg (){  
    16.             var iframe = document.getElementById('proxy');  
    17.             var win = iframe.contentWindow;  
    18.             win.postMessage(obj,'http://wozien.com');  
    19.         }  
    20.           
    21.     script>  
    22. body>  
    23. html>  
    2.在远程页面b.html中监听message事件,先通过origin属性判断下数据来源的域是否可信任,加强安全措施。具体代码如下:
    [html]  view plain  copy
    1. >  
    2. <html>  
    3. <head>  
    4.     <title>title>  
    5.     <script type="text/javascript">  
    6.         window.onmessage = function(e){  
    7.             if(e.origin !== 'http://localhost') return;  
    8.             console.log(e.origin+' '+e.data.msg);  
    9.         }  
    10.     script>  
    11. head>  
    12. <body>  
    13.     <p>this is my serverp>  
    14. body>  
    15. html>  

2.window.name

有三个页面:

    a.com/app.html:应用页面。
    a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。
    b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。

实现起来基本步骤如下:

    在应用页面(a.com/app.html)中创建一个iframe,把其src指向数据页面(b.com/data.html)。
    数据页面会把数据附加到这个iframe的window.name上,data.html代码如下:

?
1
2
3
4

    在应用页面(a.com/app.html)中监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件(代理文件和应用页面在同一域下,所以可以相互通信)。app.html部分代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

    获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)。

?
1
2
3
4
5

总结起来即:iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。有三个页面:

    a.com/app.html:应用页面。
    a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。
    b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。

实现起来基本步骤如下:

    在应用页面(a.com/app.html)中创建一个iframe,把其src指向数据页面(b.com/data.html)。
    数据页面会把数据附加到这个iframe的window.name上,data.html代码如下:

?
1
2
3
4

    在应用页面(a.com/app.html)中监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件(代理文件和应用页面在同一域下,所以可以相互通信)。app.html部分代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

    获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)。

?
1
2
3
4
5

总结起来即:iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

3.jsonp

JSONP具体实现

1.首先看下ajax中如果进行跨域请求会如何。 
前端代码在域www.practice.com下面,使用ajax发送了一个跨域的get请求


<html>
<head> <title>GoJSONPtitle> head> <body> <script type="text/javascript"> function jsonhandle(data){ alert("age:" + data.age + "name:" + data.name); } script> <script type="text/javascript" src="jquery-1.8.3.min.js"> script> <script type="text/javascript"> $(document).ready(function(){ $.ajax({ type : "get", async: false, url : "http://www.practice-zhao.com/student.php?id=1", type: "json", success : function(data) { jsonhandle(data); } }); }); script> body> html>

后端PHP代码放在域www.practice-zhao.com下,简单的输出一段json格式的数据

jsonhandle({
    "age" : 15, "name": "John", })

当访问前端代码http://www.practice.com/gojsonp/index.html 时 chrome报以下错误 
这里写图片描述
提示了不同源的URL禁止访问

2.下面使用JSONP,将前端代码中的ajax请求去掉,添加了一个script标签,标签的src指向了另一个域www.practice-zhao.com下的remote.js脚本


<html>
<head> <title>GoJSONPtitle> head> <body> <script type="text/javascript"> function jsonhandle(data){ alert("age:" + data.age + "name:" + data.name); } script> <script type="text/javascript" src="jquery-1.8.3.min.js"> script> <script type="text/javascript" src="http://www.practice-zhao.com/remote.js">script> body> html>

这里调用了跨域的remote.js脚本,remote.js代码如下:

jsonhandle({
    "age" : 15, "name": "John", })

也就是这段远程的js代码执行了上面定义的函数,弹出了提示框 
JS跨域:window.postMessage + window.name +jsonp_第1张图片

3.将前端代码再进行修改,代码如下:


<html>
<head> <title>GoJSONPtitle> head> <body> <script type="text/javascript"> function jsonhandle(data){ alert("age:" + data.age + "name:" + data.name); } script> <script type="text/javascript" src="jquery-1.8.3.min.js"> script> <script type="text/javascript"> $(document).ready(function(){ var url = "http://www.practice-zhao.com/student.php?id=1&callback=jsonhandle"; var obj = $('
                    
                    

你可能感兴趣的:(JS跨域:window.postMessage + window.name +jsonp)