JS跨域通信方法及SF相关问题
JS跨域通信方法及SF相关问题
Table of Contents
1 背景
目前客服操作处理平台查询订单及退款操作的实时性非常差,主要是由于Salesforce通过后台apex类以Web服务API的形式调用点评内部数据,严重依赖于SF数据中心访问DP网络的链路稳定性。所以我们提出了一个新的技术方案,将SalesForce与DP内部系统进行集成,在SalesForce页面中通过JS直接调用DP内部数据。旧方案与新方案可以用如下两张图表示: 1.旧方案 2.新方案 在新方案的实施中需要解决一个重要的问题就是JS的跨域通信问题。由于浏览器同源策略的限制,不同域之间属性和操作是无法直接交互的,所以在这个时候,开发者多多少少需要一些方案来突破这些限制。跨域问题涉及的地方也很多,目前网上也可以找到各种解决方法1,在尝试了iframe的跨域通信和多种ajax的跨域通信示例后,总结了两种比较推荐的方式。分享如下:
2 跨域通信方法
2.1 iframe 的跨域通信
iframe的跨域通信比较推荐的是采用信使的方式。基本地原理是在iframe的内部再创建一个iframe(称之为信使),父子页面轮询信使的window.name,父子页面各自使用变量保存window.name,轮询时发现有变化即被视为收到消息。摘自1.
作为一个通用的解决方案,目前已经有人提供一个js文件,封装通信的接口,需要通信的页面只要加载js文件就行。js的下载地址见2.
调用的js如下:
// 父页面中 // 初始化信使, 告知与其交互的iframe引用 var messenger = Messenger.initInParent(iframeEl); // 监听消息 messenger.onmessage = function (data) { ... }; // 发送消息 messenger.send(message);
// iframe中 // 初始化信使 var messenger = Messenger.initInIframe(); // 监听消息 messenger.onmessage = function (data) { ... }; // 发送消息 messenger.send(message);
2.2 ajax的跨域通信问题
ajax的跨域通信方式比较推荐的是jquery自带的jQuery.getJSON(url,function)方法通过jsonp的数据方式调用。基本的原理是通过使用jsonp这种类型,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面。服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求。意思就是远程服务端需要对返回的数据做下处理,根据客户端提交的callback的参数,返回一个callback(json)的数据,而客户端将会用script的方式处理返回数据5, 6。
客户端跨域的代码可以简单写成如下形式:
jQuery.getJSON("http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?", function(data) { $.each(data.postalcodes, function(i, n){ alert(n.adminName2); }); });
http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
该地址为互联网上一个现成的JSONP服务,可以用来做Demo。刚刚在本地验证了下这种ajax跨域请求的可行性。
如果需要自己写服务器端的jsonp数据返回,可以参考7。
2.3 采用js调用的优势和iframe及ajax各自的应用场景
改成SF页面通过JS方式调用DP内部数据会提升数据获取的实时性。iframe比较适合于一片完整的区域,可以有自己的js和css效果,ajax比较适用于SF局部文字区域的刷新。
2.4 遇到的问题
目前将本地验证通过的js代码在SF页面中运行来调用
http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
没有响应,待进一步研究。
3 附1:sfdc的Mixed_DML_OPERATION错误解决方法
同时也附带分享一个SFDC在UT的时候遇到的一个MIXED_DML_OPERATION问题,在google上搜到了一篇文章来解决这个问题8.这个问题一般发生的场景描述如:
You can easily run into this error if you are trying to perform DML on setup and non-setup objects in the same transaction. Non-Setup objects can be any one of standard objects like Account or any custom object, here are few examples of the Setup Objects Group1 GroupMember QueueSObject User2 UserRole UserTerritory Territory
解决方法:利用该网页中封装的MixedDMLOps.cls在报错的操作SF数据库的地方使用该类的增删改查方法就行。如 insert g 改成MixedDMLOps(g)即可。
4 附2:java操作sf对象
分享下以前写的java操作sf对象的博文。见http://www.cnblogs.com/csophys/archive/2013/03/08/2950419.html
Footnotes:
1 http://www.alloyteam.com/2012/08/lightweight-solution-for-an-iframe-cross-domain-communication/
2 http://biqing.alloyteam.com/lab/messenger/messenger.js
3 http://www.alloyteam.com/wp-content/uploads/2012/08/parent.html
4 https://github.com/biqing/MessengerJS
5 http://justcoding.iteye.com/blog/1366102
6 http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/
7 http://www.open-open.com/lib/view/open1334026513327.html
8 http://www.tgerm.com/2012/04/mixeddmloperation-dml-operation-on.html