代理转发

项目是前后端分离,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(也就是我们项目开发能处理的地方),我们根据这个高度再去动态设置模态窗的高度,以达到模态窗能出现在当前视图内(此时,弹窗依然是随着鼠标滚动而上下滚动的,但是效果已经好很多了,起码已经能让用户看到了,捂脸~~~)。当然了,写鼠标滚动监听事件会涉及到函数节流,此处就不多阐述了。

炒股大赛项目中遇到的跨域情况相关推荐

  1. vue php跨域,Vue 项目中遇到的跨域问题及解决方法(后台php)

    问题描述 前端 vue 框架,后台 php,百度跨域问题后台加这段代码 header("Access-Control-Allow-Origin: *"); 加了之后报这个错: Th ...

  2. ssm把图片保存到项目中_项目中的图片跨域问题解决方式

    现象 首先,在生产环境中,由于进行编辑图片时,将图片回显到ReactCrop组件中进行可裁剪编辑,然而回显时,需要将图片转化为base64的格式或者blob对象, 此时需要将图片次绘制成canvas进 ...

  3. 【全栈项目上线(vue+node+mongodb)】06.nodejs服务上线(生产环境前后分离的vue项目中怎么解决跨域问题)...

    以下操作使用下面项目为案例 https://github.com/itguide/vnshop ## 启动node服务 克隆好项目后记得把依赖包安装好 npm i 使用 node 启动node服务 c ...

  4. vue php axios 跨域,在vue项目中,使用axios跨域处理

    下面我就为大家分享一篇在vue项目中,使用axios跨域处理,具有很好的参考价值,希望对大家有所帮助. 跨域,一个很是让人尴尬的问题,有些人可以在后台中设置请求头,但是很多前端并不具备后台的知识,并无 ...

  5. java解决跨域问题_Java项目中如何解决跨域问题

    Java项目中如何解决跨域问题 发布时间:2020-11-11 16:00:40 来源:亿速云 阅读:91 作者:Leah Java项目中如何解决跨域问题?很多新手对此不是很清楚,为了帮助大家解决这个 ...

  6. 解决vue项目中的前端跨域问题

    什么是跨域 正常情况下,我们使用ajax请求的数据都在自己的服务器上.但在一些特定的场景中,我们需要获取到别人的服务器上的数据,也就是在自己的服务器中的ajax要请求到别人的服务器的网址,这就是跨域. ...

  7. 项目中的图片跨域问题解决方式

    现象 首先,在生产环境中,由于进行编辑图片时,将图片回显到ReactCrop组件中进行可裁剪编辑,然而回显时,需要将图片转化为base64的格式或者blob对象, 此时需要将图片次绘制成canvas进 ...

  8. mui后端开发php,PHP解决mui中ajax的跨域问题

    什么是跨域访问 在A网站中,我们希望使用Ajax来获得B网站中的特定内容.如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题.你可以理解为两个域名之间不能跨过域名来发送请求或者请求数据,否则就 ...

  9. Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)...

    一.前言 去年年底支付宝的被克隆漏洞被爆出,无独有偶就是腾讯干的,其实真正了解这个事件之后会发现,感觉是针对支付宝.因为这个漏洞找出肯定花费了很大劲,主要是因为支付宝的特殊业务需要开启了WebView ...

最新文章

  1. Android中removeCallbacks失效原因
  2. 免校准的电量计量芯片_万物互联,开启智慧计量新时代—2020年中国物联网计量创新发展论坛在济南举办...
  3. 详解@Autowired、@Qualifier和@Required
  4. 【实践】美团到店综合业务场景下的知识图谱构建与应用实践.pdf(附下载链接)...
  5. 我为什么离开国企,回到互联网内卷?
  6. 所有win7机器都必须要做的一个优化!作用:让系统流畅,减少卡顿
  7. 【3.2】抽象基类(abc模块)
  8. 直播预告|阿里云容器网络文件系统发布会
  9. Vue框架实例成员及项目搭建
  10. 阿里巴巴Java开发手册(2018-2021泰山版整理)
  11. 设计模式之中介者模式
  12. 深度学习与计算机视觉教程(8) | 常见深度学习框架介绍(CV通关指南·完结)
  13. HashSet为什么要设置PRESENT
  14. 一种绘制有向图的方法<TSE93> - 1. 引言
  15. 前端入门学习阶段(3)
  16. iPhone4S大跌4000港元成跌价王 水货商谨慎进货
  17. 学习OSPF,有这一篇就够了
  18. 如何更改安卓设备的序列号?
  19. 星际密码(编程题解)
  20. 分布式session解决——Spring-data-redis

热门文章

  1. Vue面试题100问
  2. html添加添加只读属性,JavaScript如何将readonly属性添加到input标签
  3. ubuntu备份系统,制作可以启动的 ISO
  4. 《新100个基本》 自我更新指南 蒲松太郎 (日)
  5. java openoffice 安装_centos 7 安装 openoffice java jodconverter
  6. 4个mysql客户端工具的比较
  7. MVCC详解,深入浅出简单易懂
  8. 力扣刷题:单词搜索(C++实现)——记忆回溯方法
  9. zygote启动流程
  10. 操作系统如何管理CPU