炒股大赛项目中遇到的跨域情况
代理转发
项目是前后端分离,api和node不是部署在同一个域名下,所以前端的server.js就用到了代理转发来解决跨域请求api接口的问题。
// server.jsconst proxy = require('express-http-proxy');
// api接口转发,config.api是接口的实际地址
app.use('/api', proxy(config.api, {forwardPath: (req, res) => {return require('url').parse(req.url).path;}
}));
jsonp
大赛的首页,由于PV量比较大,为了减轻服务器的压力,首页涉及到调用json数据的接口一律转化为静态化数据。
后端把首页需要展示的json数据处理成一份txt文件(其他文件格式也可),内容格式如下:
// finalUserList.txt
// json数据外面包裹了一个函数名,finalList(jsonData)
finalList(
{vstockZoneName: "总决赛",page: {pageNo: 1,pageSize: 10,totalItems: 20,totalPages: 2},vstockZoneId: 1000000,list: [{dayRevenueRate: 0.07487,positionRatio: 0.86,revenueRank: 1,revenueRate: 0.2763,totalAsset: 1276301.8823,totalRevenueRate: 0.2763,userNick: "筷子兄弟",weekRevenueRate: 0.10865}],issueDate: 20170321,weekDefines: [{beginDate: 20170313,endDate: 20170317,periodTypeStr: "WEEK",zoneId: 1000000},{beginDate: 20170320,endDate: 20170321,periodTypeStr: "WEEK",zoneId: 1000000}]issueDateStr: "2017-03-21 15:00",showPage: "true",zoneId: 1000000
}
)
定义一个回调函数,然后用jsonp请求这份txt文件:
function finalList(data) {console.log(data); // jsonp请求成功时,执行此回调函数,即拿到了json数据
}
定义的回调函数的名字和txt文件中的函数名字是一样的,这样才能拿到数据。实际上,回调函数的名字前端应该是可以自定义的,比如这样:
<script src="htpp://abc.com/finalUserList.txt?callback=callbackFuncName"></script>
后端拿到callback参数值,再自动生成对应的函数名,但这样无疑又增加了服务端的工作量。由于项目中调用的静态化数据接口也不算多,我们就直接约定死了回调函数的名字。
jsonp的原理:Web页面上调用js文件时不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>)。
因此,我们在html文件中动态创建<script>标签即可获取跨域资源:
var script = document.createElement('script');
script.setAttribute('src', 'http://abc.com/finalUserList.txt');
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
function finalList(data) {console.log(data)
}
postMessage
postMessage()
方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
页面与其打开的新窗口通信
多窗口之间通信
页面与嵌套iframe通信
项目中单点登录功能采用的是嵌套iframe形式。我们有模拟炒股大赛和实盘炒股大赛两个项目,域名不一样,是分开部署的。但是大赛之间又有联系,同属于“xxx”项目,用户在网页之间跳转的时候是不区分模拟大赛还是实盘大赛的,所以,单点登录的需求就产生了:当用户在模拟盘登录成功后,跳转到实盘页面的时候,实盘也实现了自动登录,反之亦然。
我们采用的方法是:在模拟盘登录的地方,嵌套了一个opacity: 0
的iframe,其src属性地址为实盘的某一个页面URL。当模拟盘登录成功的时候,会返回一个包含用户信息的token,修改iframe的src = URL + '?' + token
。然后在实盘对应的页面写js逻辑:获取URL中的token值,把token值传给后端以实现登录功能。
单点登录功能理论上是实现了,但是如果模拟盘登录的时候,一登录成功就立即跳转到其他页面的话(一般逻辑也是这样的,有个单独的登录页面,登录成功之后跳转到某一个默认的页面),登录页就消失了,所嵌入的iframe也消失了。一旦iframe消失,实盘项目对应的登录实现也就停止了。
所以,模拟盘登录成功之后不能立马就跳转,要等实盘那边返回一个登录成功与否的信息,二者之间的通信用的就是postMessage
。
// 实盘登录的处理
API.singleLogin({'token': token}).then(function(data) {if (data.errorNo == 0) {// 实盘登录成功,向模拟盘发送状态信息window.parent.postMessage('autoLoginSuceess', '*')...// 写cookie等其他操作...}
});// 模拟登录的处理
API.login({ mobile: xxx, password: *** }).then(function (data) {if (data.errorNo == 0) {...// 写cookie等其他操作...// 单点登录相关处理$('iframe').attr('src',URL + data.token); // URL加上token参数var timesRun = 0;var interval = setInterval(function() {// 监听实盘iframe传回的信息window.addEventListener('message', function(ev){// 一旦返回信息,则立即执行跳转操作if (ev.data == 'autoLoginSuceess') {clearInterval(interval);// 跳转页面操作}}, false);timesRun += 1;// 如果1s之后实盘还没返回信息,则模拟盘正常跳转if (timesRun > 5) {clearInterval(interval);// 跳转页面操作}}, 200);}
});
大致处理过程就如上述代码所示,关于postMessage更详细的用法请自行查阅资料。
其实项目中用到postMessage的还有另一个地方,也更简介地说明了postMessage的用法。上面我记述了登录中用到的postMessage,一是为了说明postMessage的用法,第二个也是想记录一下单点登录的做法。
现在简要地说一下另一处用到postMessage的地方。
我们的项目是三方合作的那种,我们做出的页面最后都是嵌入在qq域名下的,所以也是一种iframe嵌入。Bootstrap的模态窗很好用,当在本地开发时是完全ok的:页面不能滚动,弹窗的位置是固定在当前视窗内的。但是一旦项目被嵌入到qq域名下,就出问题了——弹窗是随着鼠标滚动而上下滚动的,如果用户滚动到页面比较靠下的位置,点击按钮弹出模态窗的话,此时模态窗是靠在页面顶端的,造成一种用户看不到弹窗的情况。
我们采取的措施是:在qq域名下的页面写鼠标滚动的监听事件,监听鼠标滚动了多高,然后把这个高度传给iframe(也就是我们项目开发能处理的地方),我们根据这个高度再去动态设置模态窗的高度,以达到模态窗能出现在当前视图内(此时,弹窗依然是随着鼠标滚动而上下滚动的,但是效果已经好很多了,起码已经能让用户看到了,捂脸~~~)。当然了,写鼠标滚动监听事件会涉及到函数节流,此处就不多阐述了。
炒股大赛项目中遇到的跨域情况相关推荐
- vue php跨域,Vue 项目中遇到的跨域问题及解决方法(后台php)
问题描述 前端 vue 框架,后台 php,百度跨域问题后台加这段代码 header("Access-Control-Allow-Origin: *"); 加了之后报这个错: Th ...
- ssm把图片保存到项目中_项目中的图片跨域问题解决方式
现象 首先,在生产环境中,由于进行编辑图片时,将图片回显到ReactCrop组件中进行可裁剪编辑,然而回显时,需要将图片转化为base64的格式或者blob对象, 此时需要将图片次绘制成canvas进 ...
- 【全栈项目上线(vue+node+mongodb)】06.nodejs服务上线(生产环境前后分离的vue项目中怎么解决跨域问题)...
以下操作使用下面项目为案例 https://github.com/itguide/vnshop ## 启动node服务 克隆好项目后记得把依赖包安装好 npm i 使用 node 启动node服务 c ...
- vue php axios 跨域,在vue项目中,使用axios跨域处理
下面我就为大家分享一篇在vue项目中,使用axios跨域处理,具有很好的参考价值,希望对大家有所帮助. 跨域,一个很是让人尴尬的问题,有些人可以在后台中设置请求头,但是很多前端并不具备后台的知识,并无 ...
- java解决跨域问题_Java项目中如何解决跨域问题
Java项目中如何解决跨域问题 发布时间:2020-11-11 16:00:40 来源:亿速云 阅读:91 作者:Leah Java项目中如何解决跨域问题?很多新手对此不是很清楚,为了帮助大家解决这个 ...
- 解决vue项目中的前端跨域问题
什么是跨域 正常情况下,我们使用ajax请求的数据都在自己的服务器上.但在一些特定的场景中,我们需要获取到别人的服务器上的数据,也就是在自己的服务器中的ajax要请求到别人的服务器的网址,这就是跨域. ...
- 项目中的图片跨域问题解决方式
现象 首先,在生产环境中,由于进行编辑图片时,将图片回显到ReactCrop组件中进行可裁剪编辑,然而回显时,需要将图片转化为base64的格式或者blob对象, 此时需要将图片次绘制成canvas进 ...
- mui后端开发php,PHP解决mui中ajax的跨域问题
什么是跨域访问 在A网站中,我们希望使用Ajax来获得B网站中的特定内容.如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题.你可以理解为两个域名之间不能跨过域名来发送请求或者请求数据,否则就 ...
- Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)...
一.前言 去年年底支付宝的被克隆漏洞被爆出,无独有偶就是腾讯干的,其实真正了解这个事件之后会发现,感觉是针对支付宝.因为这个漏洞找出肯定花费了很大劲,主要是因为支付宝的特殊业务需要开启了WebView ...
最新文章
- Android中removeCallbacks失效原因
- 免校准的电量计量芯片_万物互联,开启智慧计量新时代—2020年中国物联网计量创新发展论坛在济南举办...
- 详解@Autowired、@Qualifier和@Required
- 【实践】美团到店综合业务场景下的知识图谱构建与应用实践.pdf(附下载链接)...
- 我为什么离开国企,回到互联网内卷?
- 所有win7机器都必须要做的一个优化!作用:让系统流畅,减少卡顿
- 【3.2】抽象基类(abc模块)
- 直播预告|阿里云容器网络文件系统发布会
- Vue框架实例成员及项目搭建
- 阿里巴巴Java开发手册(2018-2021泰山版整理)
- 设计模式之中介者模式
- 深度学习与计算机视觉教程(8) | 常见深度学习框架介绍(CV通关指南·完结)
- HashSet为什么要设置PRESENT
- 一种绘制有向图的方法<TSE93> - 1. 引言
- 前端入门学习阶段(3)
- iPhone4S大跌4000港元成跌价王 水货商谨慎进货
- 学习OSPF,有这一篇就够了
- 如何更改安卓设备的序列号?
- 星际密码(编程题解)
- 分布式session解决——Spring-data-redis