关于Cordova框架对URL拦截导致通信丢失问题的处理

栏目: 后端 · 前端 · 发布时间: 6年前

内容简介:昨天看了味精大佬关于hybrid框架搭建的系列文章的Cordova在iOS端是怎么通信的,我之前的文章浅析iOS-Cordova讲的很清楚了,在iOS端主要是围绕着一个queue数组进行的,具体怎么进行的本篇不做分析了,具体可以看前面提到的文章了解下。本篇主要围绕以下三点进行分析:

昨天看了味精大佬关于hybrid框架搭建的系列文章的 从零收拾一个hybrid框架(一)-- 从选择JS通信方案开始 ,不得不说大佬总结的很细致,尤其是基于WKWebView的总结很到位,文章里面提到了UIWebView基于URL拦截的方式不安全问题,实际上之前我是没有关注这个问题的,以至于后两篇还没来得及学习就陷入了沉思,那么我一直使用的Cordova框架是怎么处理这个问题的?还是说就没有处理?关于这个问题,实际上Cordova框架内部是做了处理的,本篇主要针对Cordova对于URL拦截方式进行通信做了哪些优化进行分析。

Cordova在iOS端是怎么通信的,我之前的文章浅析iOS-Cordova讲的很清楚了,在iOS端主要是围绕着一个queue数组进行的,具体怎么进行的本篇不做分析了,具体可以看前面提到的文章了解下。

本篇主要围绕以下三点进行分析:

  • 1.js在给native发送假请求的时候做了什么
  • 2.实际上js是怎样将各种参数传递给native的
  • 3.pokeNative优化了什么

js在给native发送假请求的时候做了什么

真相都在cordova.js里面,作为一个未入门的前端来说,对于cordova.js只能做一个简要分析,主要是针对上面提到的两点,看代码。

function iOSExec() {
    //删除了一些不在本篇讨论范围内的代码
    var command = [callbackId, service, action, actionArgs];
    commandQueue.push(JSON.stringify(command));
    if (!isInContextOfEvalJs && commandQueue.length == 1) {
        pokeNative();
    }
}
复制代码

在js端调用cordova插件的时候,代码会走进cordova.js里面的这个方法,push()函数实际上就是OC中的addObject:操作,commendQueue为cordova.js内维护的全局数组,commandQueue.push就是像commendQueue数组的最后面添加了一个对象,也就是被转为json格式的command对象。那么实际上在前端连续多次频繁的调用插件的时候,插件的command信息都会被存储在commandQueue中而不是把每一个通信都要去做一个假请求。通过if (!isInContextOfEvalJs && commandQueue.length == 1)这个判断可以看到如果commandQueue中的调用次数不为一,也就是说可能有多个的时候,是不会执行pokeNatie()的,pokeNative实际为发送假请求的具体实现,后面会讲到。从而也就避免了插件被频繁调用所引起的通信丢失的情况。

那么问题来了,插件的调用都被存储在了commandQueue中,native端怎么获取。这也是我们要讨论的第二个问题。

实际上js是怎样将各种参数传递给native的

那么这个问题我们需要分析下另一个函数,看代码:

iOSExec.nativeFetchMessages = function() {
    if (failSafeTimerId) {
        clearTimeout(failSafeTimerId);
        failSafeTimerId = 0;
    }
    if (!commandQueue.length) {
        return '';
    }
    var json = '[' + commandQueue.join(',') + ']';
    commandQueue.length = 0;
    return json;
};
复制代码

这是native端收到cordova.js的pokeNative发出的假请求会调用的函数,这个json对象存储的正是commandQueue中的插件调用信息,那么不难看出,实际上Cordova内通信参数并不是在URL上传递,而是JS端告诉Native过来取,大概意思就是我这有好多都取过去吧。实际上只pokeNative()了一次,那么插件调用就都被native端取走了,这样也就避免了快速的频繁的发假请求而导致通信丢失问题。

pokeNative优化了什么

实际上经过了上面两步,还是不够安全的,因为有一种情况,那就是当前端的第一次调用刚好结束的时候发生了第二次调用,这个时候已经执行了commandQueue.length = 0;函数,也就是说commandQueue已经被清空了,那么就会执行pokeNative()函数,去发一个假请求给native端,这样就导致了连续的两次假请求发生。实际上这一块cordova.js也是做了处理的,详情在pokeNative()里面,看代码:

function pokeNative() {
    //代码删减部分
    failSafeTimerId = setTimeout(function() {
        if (commandQueue.length) {
            // CB-10106 - flush the queue on bridge change
            if (!handleBridgeChange()) {
                pokeNative();
             }
        }
    }, 50);
}
复制代码

setTimeout()函数在javaScript里面相当于添加了个定时器,也就是在50毫秒之后再执行pokeNative()函数,这样也就是做了一个50毫秒的间隔,从而避免了快速的两次调用。这一块pokeNative()函数内部代码注释也有解释,通信效率会降低7%,但是毕竟这种情况不多,而且7%也在我们能接受的范围内。

总结

基于URL拦截的方式,随着JSCore和WKWebView的新特性的出现也正在被逐渐的取缔,但是Cordova框架不单单给我们提供了一种通信方式,更多的是它的设计思想,以及对hybrid框架的交互设计理念,还是非常值得我们学习的,如果有一天需要我们自己来做hybrid框架,我认为除了改变一下通信方式以外,对于Cordova框架的其他部分都是很值得我们去学习的。

本文属于原创,转载注明出处。


以上所述就是小编给大家介绍的《关于Cordova框架对URL拦截导致通信丢失问题的处理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Linux Programming Interface

The Linux Programming Interface

Michael Kerrisk / No Starch Press / 2010-11-6 / GBP 79.99

The Linux Programming Interface describes the Linux API (application programming interface)-the system calls, library functions, and other low-level interfaces that are used, directly or indirectly, b......一起来看看 《The Linux Programming Interface》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具