因为不是个单独的技术点,所以只好把整个实现过程记录下来,备个忘吧,这段时间脑子不是很好用,老是忘东西。

缘起

接入体验软件,实现所谓的“单点登录”。也就是略过那些体验软件的登录页面直接进入登录后的主界面。

因为可以和对方的技术人员沟通,一般让对方提供一个不需要验证码的用户名和密码,我来构造一个GET请求就可以了。或者更简单些,对方提供一个链接,我只要访问这个链接就可以了。

初探

这次联系的软件和之前不大一样,要求用户进去注册一个账号然后再进行登录。因为本来就没有验证码,感觉应该会比较容易。结果尝试之下发现只用用户名和密码构造一个GET请求是无法登录的。看来需要联系他们的技术人员了。

切磋

和对方说明来意,我建议对方提供一个直接登录的链接。过了一会,对方回复说不能提供,坚持要求用户从他们的登录页进行登录。进一步了解之后发现有两个问题,一是他们希望在登录页控制用户必须使用谷歌浏览器;二是他们想要收集每一个试用用户的有效资料。

第一条我提出可以在我们这边进行限制,第二条因为我们的需要,只能统一让我们的用户以省物流平台的名义去试用。对方没有再坚持要求什么,但是也不会再提供进一步的技术支持,剩下的问题只能由我自己解决了。

苦练

既然GET请求无法登录,那么就构造POST请求好了。用js构造一个表单,添加input,然后提交……但是提交表单会使当前页跳转,我们需要在新标签页打开。先尝试用window.open()打开一个空白窗口,把表单的target属性设成这个新窗口的名字。缺点是弹出窗口的话很容易被浏览器当成广告屏蔽掉。

另一个棘手的问题是,为了强制用户必须从登录页进行登录,他们使用了一种比较邪恶的办法,就是在跳转到登录页时给登录页附加了一个重定向url,这样在登录以后才会跳转到这个url指向的页面。我自己构造的请求虽然能成功登录,但之后我就跳转到了网站首页——这显然不是我想要的。

我考虑可以先去登录,登录完成后关闭页面,再打开一个体验软件主页面。既然登录用的页面打开后马上又会关闭,可以用一个隐藏的iframe来代替。试验结果很成功。同时我也深深感觉到这个方法还真够邪恶。

下面再来解决前面的那个弹窗问题。貌似这些多标签浏览器会在遇到onclick事件处理程序中的window.open()方法时会打开一个新标签页,以别的事件打开的窗口都是弹窗。估计浏览器的设计者认为点击事件是由用户自行触发,安全度较高,允许开新标签,而其他方式打开的窗口就被认为是可以当成广告窗口屏蔽的弹窗了。

我的主页面窗口只有在登录用的iframe加载完成后才可以打开,也就是说打开窗口的方法是在iframe的onload事件中执行的。那么我只好先在处理“立即体验”按钮的onclick事件处理函数中先打开一个空窗口——实际上会打开一个空标签页——然后在iframe的onload事件中给刚才打开的页面设置location,让它跳转到你想要的页面。好绕啊,我怀疑过段事件回来看我自己都弄不明白了。

上面的解决办法依然非常邪恶,试验结果也是成功的。接下来只有一点小问题需要解决了。因为每次执行“立即体验”的onclick事件处理函数时都要新建一个表单和一个iframe,设计不合理不说,从试验的结果来看只有第一次能成功,之后每次都是打开一个空标签页,而不能跳转到体验软件的主页面。

那么就先判断一下是否已经存在自行创建的表单或iframe,如果有,说明之前已经登录过了,直接打开体验软件主页面就可以了。

后话

很多不容易解决的棘手问题都可以通过iframe邪恶(或者说巧妙?)地解决掉。

还有在引用跨站内容而受到浏览器的“同源策略”限制时,可以考虑通过服务端去请求数据再发给浏览器,这样就转换成站内资源了。不过注意需要处理其中的路径问题。



blog comments powered by Disqus