编程语言
首页 > 编程语言> > JavaScript跨域方法实例详解

JavaScript跨域方法实例详解

作者:互联网

上一篇《JavaScript跨域原理》我们回顾了一下跨域的基础知识和原理,今天我们看一下实例。

实例详解

在本地玩起来,修改hosts文件增加如下的几个域名绑定作为测试:

127.0.0.1 source.test.com
127.0.0.1 target.test.com
127.0.0.1 source.test.org
127.0.0.1 target.test.org

本文所有实例都可以在 这里 下载

动态不受限标签

JSONP

源域 source.test.com/source-client.html

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>jsonp Test</title>
    <script type="text/javascript">

        // function JSONPCallback(){
        //     console.log(arguments[0])
        // }

        // function loadScript(url){
        //     var script = document.createElement('script');      
        //     script.src = url;

        //     document.head.appendChild(script);
        // }

        // loadScript("http://target.test.org:9000/getData.do?callback=JSONPCallback")

        //下面这个是jQuery风格的JSONP,更容易理解

        function getJSON(url,callback){            var script = document.createElement('script');      
            var callbackName = "ProxyFunc_" + (new Date().getTime())            window[callbackName] = function(){
                callback(arguments[0]);
            };

            script.onload = script.onratechange = function(){                if(this.readyState == 'complete'){                window[callbackName] = null;
                }
            }

            script.src = url.replace("JSONPCallback",callbackName);            document.head.appendChild(script);
        }

        getJSON("http://target.test.org:9000/getData.do?callback=JSONPCallback",function(data){            console.log(data)
        })    </script></head><body></body></html>

目标域 target.test.org:9000

var http = require("http");var url = require("url");var server = new http.Server();
server.listen(9000);

server.on("request",function(request,response){    var paramDict = url.parse(request.url,true).query;    var callback = paramDict.callback    var retData = callback + '(' +'{"status":"success",data:{"name":"test JSONP"}}'  + ')';
    response.end(retData);
});

操作方法

打开源域页面,在控制台查看拿到的数据

Form提交

这个我不会写~

window.name

源域 source.test.com/source.html

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title> window.name test</title> 
    <script type="text/javascript">
        window.name = "source shared windowname"
        alert(window.name)        window.location.href = "http://target.test.org/target.html"
    </script></head><body></body></html>

目标域 target.test.org/target.html

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>window.name test</title>
    <script type="text/javascript">
        alert(window.name)    </script></head><body></body></html>

操作

打开源域页面看 即使跳转到目标域 数据依然存在

document.domain

源域 source.test.com/source.html

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>document.domain test</title> </head><body>
    <iframe src="http://target.test.com/target.html"></iframe></body>
    <script type="text/javascript">
        document.domain = "test.com";        window.onload = function(){            var doc = window.frames[0].document;            console.log(doc.getElementById('tid').outerHTML);            console.log(doc.body.innerHTML)
            setTimeout(function(){
                doc.body.innerHTML = "data from source.test.com"
            },3000)
        }    </script></html>

目标域 target.test.com/target.html

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>document.domain test</title>
    <script type="text/javascript">
        document.domain = "test.com"
    </script></head><body>
    <p id="tid">data of target.test.com</p></body></html>

操作

打开源域页面 查看源域操作目标域dom情况

CORS

源域 source.test.com/client.html 源代码

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>cross doamin resource sharing test</title>
    <script type="text/javascript">
        var xhr = new XMLHttpRequest();

        xhr.onreadystatechange = function(){            if(xhr.readyState == 4 && xhr.status == 200){                console.log(xhr.responseText)
            }
        }

        xhr.open('POST','http://target.test.org:9000/getInfo.json',true)
        xhr.send();    </script></head><body></body></html>

目标域 target.test.org:9000

var http = require("http");var server = new http.Server();
server.listen(9000);

server.on("request",function(request,response){    //不加这个相应头,客户端会报错,无法跨越发请求
    response.setHeader("Access-Control-Allow-Origin","http://source.test.com")
    response.writeHead(200,{"Content-Type":"text/html;charset=UTF-8"});
    response.write('msg: "cross origin by cors"');
    response.end();
});

操作方法

postMessage

源域的页面嵌入加载了目标域的页面,并在两个域之间进行通信。

源域 source.test.com/source.html 源代码:

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>postMessage Test Source</title>
    <script type="text/javascript">
        window.addEventListener('message',function(evt){        console.log('source getmessage:',evt.data); 
        evt.source.postMessage('##source message##',evt.origin);
        });    </script></head><body>
    <iframe src="http://target.test.org/target.html"></iframe></body></html>

目标域 target.test.org/target.html 源代码:

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>postMessage Test Source</title>
    <script type="text/javascript">
        window.addEventListener('message',function(evt){        console.log('target getmessage:',evt.data); 
        });        window.parent.postMessage('##target message##','http://source.test.com');    </script></head><body></body></html>

操作方法

WebSocket

源域的页面中的脚本在页面加载时向目标域的服务发送信息,并接受服务返回的信息。

目标域 target.test.org:9000 源代码:

var WebSocketServer = require('ws').Server;var socketServer = new WebSocketServer({port:9000});
socketServer.on('connection',function(websocket){
    websocket.on('message',function(message){    console.log(new Date().getTime(),' received ',message) 
    websocket.send('###' + message + "###")
    });
})

源域 source.test.com/index.html 源代码:

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>WebSocket Cross Origin Test</title>
    <script type="text/javascript">
        var websocket = new WebSocket("ws://target.test.org:9000");
        websocket.onopen = function(){            console.log('websocket opened');
            websocket.send('I am opened');
        }

        websocket.onmessage = function(evt){            console.log('recevie message')            console.log(evt.data)
        }

        websocket.onclose = function(){            console.log('websocket closed')
        }

        websocket.onerror = function(){            console.log('websocket meets error')
        }    </script></head><body></body></html>

操作方式

参考资料

  1. RFC 6454 The Web Origin Concept(https://tools.ietf.org/html/rfc6454)

  2. W3C 同源策略(https://www.w3.org/Security/wiki/Same_Origin_Policy)

  3. MDN CORS(https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_C


标签:function,跨域,JavaScript,源域,source,window,详解,test,target
来源: https://blog.51cto.com/u_15127643/2773424