前段时间公司要求跨浏览器(IE/FIREFOX),跨业务系统(公司内部系统/外部系统)的情况下,进行消息的推送、获取和回调;

这里提取出精华的部分,分享下。

经过很多测试,html5的websocket(很好很强大,但是面对一个只能运行在IE8以下的,还是外部的系统,只能放弃);

加载iframe流(实际上是去请求一个controller的方法,后台采取延迟处理,但是错误异常不好处理);

最终准备采取网上的一些建议:客户端利用常规的ajax异步方式,发起获取推送的请求,服务器端采用延迟处理,在一定时间内(如1分钟),从数据库获取数据,如果没有则继续获取,超时的时候,如果还是没有数据,则返回前台,告知请求超时,且没有数据,前端继续发起新的请求;如果服务器在超时时间内,获取到了数据,则立刻返回到前端,前端做相应处理,并在处理完毕后,继续发起新的推送请求;

这个方式的好处是,异步的ajax,虽然大部分时间在获取信息,但是用户不会轻易发觉;长轮训的机制,导致请求连接不会非常频繁,可以根据需要配置服务器端的超时时间;另外服务器端的轮训机制可以进一步进行优化,目前是采用while的方式循环,应该还有改进的空间;客户端可以通过ajax的error时间,捕获到错误异常信息并告知用户;

本来这套方案已经基本成型,问题出现了,两个业务系统一个是windows下面的c#的MVC架构,一个是外部系统的linux的java的系统,域名最多只能是同根域,域名不可能完全相同;这样原本的方案就行不通,可能需要跨域访问;

我们知道jquery的jsonp方式,封装实现了跨域ajax请求的需求,但有一点问题就是,实际上jsonp的形式就不是ajax请求了,最明显的表现就是,用户可以直接利用ie浏览器导航栏边上的“X”按钮,随时清掉你的请求(实际上就是访问一个html一样的,可以随时停止);

发现这个问题之后,偶然发现webqq的工作机制是这样实现的:webqq的前端页面是在w.qq.com这个域名下的,但是通过监控发现,他获取推送信息的请求连接却是

另一个域名(根域相同)下的方法;强调下,这里很确定的是,类似人人、新浪微博、webqq、百度的hi,都是利用之前提到的ajax长轮训机制,因此这个方式是可靠的;

从图片中可以看到,webqq在前端不断的去请求d.web2.qq.com下面的某个url,来获取推送信息,时间不等,超过一定时间就会返回超时;

回来看下,如何实现跨子域的ajax请求。通过观察前端js代码,发现在当前页面下,已iframe的形式嵌入了一个d.web2.qq.com下面的html页面,在该页面下请求ajax,实际上是

本地的常规ajax请求了,所以页面不会刷新,用户也不能简单通过浏览器终止该请求。豁然开朗,原来如此;

最后总结下,当我们需要w.mix.com域名下,不刷新页面实现ajax请求到s.mix.com下的某个方法,可在w.mix.com下嵌入一个部署在s.mix.com下的html,在这个html下实现常规的ajax请求即可;

至于推送机制,在服务器端采用延迟处理,客户端依赖服务器端的响应进行请求,这样就实现了长轮训的机制;

另外,两个页面虽然根域相同,但是如果直接嵌入的iframe中的js或者document元素,是没有权限的,需要把两个html的域名都指向同一根域:document.domain="mix.com“;

这样就不会有问题了。

 

PS:以上设置域名方法在最后的实现中还是没能实现,那套外部的系统,用了大量的frameset这样的。。古老的东西。。。最终还是通过jsonp的形式实现,没有办法只能处理下用户终止请求的错误信息了;

posted on 2013-10-29 09:58  mixls1234  阅读(273)  评论(0编辑  收藏  举报