有时候会遇到傻X需求,好比前端单点登录!遇到需求,就要去想解决办法, 这里我给你们作一个简单的前端单点登录的解决方案, 用到的就是postMessage跨域信息传输以及onstorage的监听。 本文用到的知识点 koa架设静态资源服务、跨域、postMessage的用法 、onstorage监听storage
咱们这里用koa2来搭建两个服务到不一样的端口,来模拟一下真正的工做中须要出现的跨域状况。
很是的简单 主要用到 koa-static这个中间件
搭建起来也是很是容易的,若是你们想学node相关的知识 能够加我微信shouzi_1994 或者在博客下面留言你的联系方式 这里就很少说废话了 直接上代码 视频内会有详细的搭建步骤html
// localhost:4000 const Koa = require('koa'); const path = require('path') const static = require('koa-static') const app = new Koa(); //设置静态资源的路径 const staticPath = './static' app.use(static( path.join( __dirname, staticPath) )) console.log("服务启动在4000端口") app.listen(4000); // localhost:3000 const Koa = require('koa'); const path = require('path') const static = require('koa-static') const app = new Koa(); //设置静态资源的路径 const staticPath = './static' app.use(static( path.join( __dirname, staticPath) )) console.log("服务启动在4000端口") app.listen(4000);
咱们首先来看一下 postMessage的API前端
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其余窗口的一个引用,好比iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
message
将要发送到其余 window的数据。它将会被结构化克隆算法序列化。这意味着你能够不受什么限制的将数据对象安全的传送给目标窗口而无需本身序列化。[1]
targetOrigin
经过窗口的origin属性来指定哪些窗口能接收到消息事件,其值能够是字符串""(表示无限制)或者一个URI。在发送消息的时候,若是目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者彻底匹配,消息才会被发送。这个机制用来控制消息能够发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤其重要,必须保证它的值与这条包含密码的信息的预期接受者的origin属性彻底一致,来防止密码被恶意的第三方截获。若是你明确的知道消息应该发送到哪一个窗口,那么请始终提供一个有确切值的targetOrigin,而不是。不提供确切的目标将致使数据泄露到任何对数据感兴趣的恶意站点。
transfer 可选
是一串和message 同时传递的 Transferable 对象. 这些对象的全部权将被转移给消息的接收方,而发送一方将再也不保有全部权。node
怎么样是否是很容易理解,这里给你们中文化一下。
要传输的那个(父)子窗口.postMessage(传输的内容, 传输到哪一个地址, [权限是否转移(通常不用)]);算法
提早说一下,要想跨域传输,必须是父子页面,也就是说,是经过js Open的页面,或者ifream嵌套的页面
好了 咱们开始来写代码跨域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <!-- postMessage和iframe解决普通的跨域问题 --> 我是端口3000网站的内容 <button onclick="send()">发消息给儿子</button> <iframe style="display:none" src="http://localhost:4000" frameborder="0"></iframe> <script> function send() { window.frames[0].postMessage({a:"1"},"http://localhost:4000"); // 触发跨域子页面的messag事件 } window.addEventListener('message', function(event) { console.info('儿子来信了', event); }, false); </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <!-- postMessage和iframe解决普通的跨域问题 --> 我是端口4000网站的内容 <button onclick="send()">发消息给爸爸</button> <iframe style="display:none" src="http://localhost:4000" frameborder="0"></iframe> <script> window.addEventListener("message",function(event){ console.log("爸爸来信了:", event) },false) function send() { parent.postMessage({a:1}, 'http://localhost:3000'); // } </script> </body> </html>
写到这里咱们已经实现了父子页面的跨域通信,可是这个通信只发生在一个窗口内啊,并无达到我想要的效果,该怎么办呢。浏览器
到这里你们须要思考,什么东西是浏览器上的全部同域名网站都能看到的呢?
没错,storage,咱们只须要对这个进行监听就行了。安全
这里咱们选择监听 loacalStorage 如今咱们对子页面作一下改进微信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <!-- postMessage和iframe解决普通的跨域问题 --> 我是端口4000网站的内容 <button onclick="send()">发消息给爸爸</button> <iframe style="display:none" src="http://localhost:4000" frameborder="0"></iframe> <script> window.addEventListener("message",function(event){ console.log("爸爸来信了:", event) var data = JSON.stringify(event.data) window.localStorage.setItem("data",data) },false) window.onstorage(function(st){ console.log(st.key,st.value) }) function send() { parent.postMessage({a:1}, 'http://localhost:3000'); // } </script> </body> </html>
看,咱们是否是到如今就可以针对跨域传输的内容作出响应了呢?app
如今咱们作到了两个页面的跨域通信,那么三个到多个的跨域通信怎么作呢?其实一个道理啦。如今道理说给你了,写法本身去体验一下吧。koa
你们有什么工做上的坎,想不通的问题,学习上的难点,均可以给我微信发信息,或者在博客评论,我都会尽力帮助你们,经典问题我会作成视频和你们分享。基础入门视频我仍是会持续制做,不过我以为教基础是真的难,还好我手里还有不少免费的入门视频,须要的也能够找我。彻底免费。