ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript跨域方法实例详解

2021-05-13 14:56:52  阅读:149  来源: 互联网

标签:function 跨域 JavaScript 源域 source window 详解 test target


上一篇《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>

操作方式

  • npm install ws

  • node 启动目标域的socket server

  • 浏览器打开源域的页面

  • 在控制台可以看到客户端和服务端交互的消息

参考资料

  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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有