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>
操作方式
npm install ws
node 启动目标域的socket server
浏览器打开源域的页面
在控制台可以看到客户端和服务端交互的消息
参考资料
RFC 6454 The Web Origin Concept(https://tools.ietf.org/html/rfc6454)
W3C 同源策略(https://www.w3.org/Security/wiki/Same_Origin_Policy)
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