mpaas离线包pushwindow如何获得启动参数、如何跳页传参、passData如何从H5传给下一个H5、mpaas的高级js注入方法

 

猜想1:js注入。WKUserContentController分类重写addUserScript方法打印

#import "WKUserContentController+YYY.h"

@implementation WKUserContentController (YYY)
- (void)addUserScript:(WKUserScript *)userScript;{
    NSLog(@"%@",userScript.source);
}

@end

发现没有影响

 

猜想2:h5与原生交互获取。替换WKWebView的evaluateJavaScript方法


@implementation WKWebView (YYY)



+(void)load{
    
 
    {
        Method originalMethod = class_getInstanceMethod([NSClassFromString(@"WKWebView") class], @selector(evaluateJavaScript:completionHandler:));
        Method swizzledMethod = class_getInstanceMethod([self class], @selector(evaluateJavaScript:completionHandlerS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    
 
}
-(void)evaluateJavaScript:(NSString *)javaScriptString completionHandlerS:(void (^)(id _Nullable  str7 , NSError * er7))completionHandler{
    

    NSLog(@"wk原生调用h5 %@ ",javaScriptString);
    
    [self evaluateJavaScript:javaScriptString completionHandlerS:^(id  _Nullable str, NSError *er) {
    }];
    
    [self evaluateJavaScript:javaScriptString completionHandlerS:completionHandler];

        
    
    
}
@end

 

可以发现部分页面使用pushwindow跳页的passdata在getStartupParams时传过去是可以的。

部分页面不可以

 

猜不出来了,上hopper

1.先看这个void -[JsApiHandler4PushWindow handler:context:callback:](void * self, void * _cmd, void * arg2, void * arg3, void * arg4) {


loc_1016df171:
    r14 = [[r12 objectForKeyedSubscript:@"passData"] retain];
    rcx = &var_-424;
    rdx = rcx;
    rax = [NSDictionary dictionaryWithObjects:rdx forKeys:rcx count:0x0];
    rax = [rax retain];
    r15 = [_NBDictionary(r14, rax) retain];
    [rax release];
    [r14 release];
    r12 = var_-336;
    if (r15 != 0x0) {
            rax = [r12 viewController];
            rax = [rax retain];
            r14 = rax;
            rax = [rax viewControllerProxy];
            rax = [rax retain];
            rcx = r15;
            [rax setExpando:@"kNBViewControllerProxyPassData" withValue:rcx, 0x0];
            [rax release];
            [r14 release];
    }

搜索passData可出现上面的代码

 

2.搜"kNBViewControllerProxyPassData"

0000000102666fe8         dq         ___CFConstantStringClassReference, 0x7c8, _amf_base64EncodedStringWithWrapWidth:.lookup+145874, 0x1e ;

"kNBViewControllerProxyPassData", DATA XREF=

-[NBPlugin4HandleProxyRequest passDataString:]+146,

-[JsApiHandler4PushWindow handler:context:callback:]+7798,

-[Plugin4HandleProxyRequest passDataString:]+146

 

 

-[NBPlugin4HandleProxyRequest passDataString:]方法不走

重写Plugin4HandleProxyRequest的passDataString方法可以发现,传空页面会白页

调用堆栈是

可以看到是在拦截请求的时候做的。

调用-passDataString传过来的参数是PSDProxyEvent类型,可以获取到当前控制器

 

void * -[Plugin4HandleProxyRequest passDataString:](void * self, void * _cmd, void * arg2) {
    rbx = [arg2 retain];
    r14 = @"";
    [r14 retain];
    var_-48 = rbx;
    rax = [rbx context];
    rax = [rax retain];
    r15 = [[rax currentViewController] retain];
    [rax release];
    rax = [r15 viewControllerProxy];
    rax = [rax retain];
    r12 = [[rax getExpando:@"kNBViewControllerProxyPassData"] retain];
    [rax release];
    if (r12 != 0x0) {
            rax = [NSJSONSerialization dataWithJSONObject:r12 options:0x0 error:0x0];
            rax = [rax retain];
            r13 = rax;
            if (rax != 0x0) {
                    r14 = [[NSString alloc] initWithData:r13 encoding:0x4];
                    [@"" release];
            }
            else {
                    r14 = @"";
            }
            [r13 release];
            if ([r14 isKindOfClass:[NSString class]] == 0x0) {
                    [@"" retain];
                    [r14 release];
                    r14 = @"";
            }
            if (0x0 == 0x0) {
                    if ([r14 length] != 0x0) {
                            rbx = [[NSString stringWithFormat:@"window.ALIPAYH5STARTUPPARAMS.passData='%@';", r14] retain];
                            [r14 release];
                            r14 = rbx;
                    }
                    [r12 release];
                    [r15 release];
                    [var_-48 release];
                    rax = [r14 autorelease];
            }
            else {
                    rax = objc_exception_rethrow();
            }
    }
    else {
            if ([r14 length] != 0x0) {
                    rbx = [[NSString stringWithFormat:@"window.ALIPAYH5STARTUPPARAMS.passData='%@';", r14] retain];
                    [r14 release];
                    r14 = rbx;
            }
            [r12 release];
            [r15 release];
            [var_-48 release];
            rax = [r14 autorelease];
    }
    return rax;
}

上面代码显示是拼接了参数                          

rbx = [[NSString stringWithFormat:@"window.ALIPAYH5STARTUPPARAMS.passData='%@';", r14] retain];
 

拼好之后怎么用呢

void * -[Plugin4HandleProxyRequest getInjectJSDataWithEvent:](void * self, void * _cmd, void * arg2) {
    rdx = arg2;
    var_-72 = self;
    rax = [rdx retain];
    var_-80 = rax;
    rax = [rax context];
    rax = [rax retain];
    r12 = rax;
    rax = [rax currentViewController];
    rax = [rax retain];
    r15 = rax;
    rax = [rax options];
    rax = [rax retain];
    r13 = rax;
    rax = [rax appId];
    rax = [rax retain];
    rbx = rax;
    rdi = rbx;
    if (rax == 0x0) {
            rdi = @"";
    }
    rax = [rdi retain];
    rdi = rbx;
    rbx = rax;
    [rdi release];
    [r13 release];
    [r15 release];
    [r12 release];
    rdx = @selector(length);
    if (([rbx respondsToSelector:rdx] != 0x0) && ([rbx length] == 0x0)) {
            var_-64 = rbx;
            rax = [var_-80 request];
            rax = [rax retain];
            r12 = rax;
            rax = [rax mainDocumentURL];
            rax = [rax retain];
            r13 = [[rax host] retain];
            [rax release];
            [r12 release];
            if ([r13 length] != 0x0) {
                    var_-56 = @"^\d+\.hybrid\.alipay-eco\.com";
                    rax = [NSArray arrayWithObjects:rdx count:0x1];
                    rax = [rax retain];
                    r15 = _H5RegexTest(r13, rax);
                    [rax release];
                    if (r15 != 0x0) {
                            rax = [r13 componentsSeparatedByString:@"."];
                            rax = [rax retain];
                            r12 = [[rax firstObject] retain];
                            [var_-64 release];
                            [rax release];
                    }
                    else {
                            r12 = var_-64;
                    }
            }
            else {
                    r12 = var_-64;
            }
            [r13 release];
    }
    else {
            r12 = rbx;
    }
    r15 = [[var_-72 h5GeoLocationJSContent] retain];
    var_-160 = [[var_-72 h5PerformanceTimingJSContent:var_-80] retain];
    var_-152 = [[var_-72 h5PerformanceJSContent] retain];
    var_-144 = [[var_-72 h5ShareJSContent] retain];
    var_-136 = [[var_-72 h5PSDAccessTypeJSContent:var_-80] retain];
    var_-128 = [[var_-72 h5DynamicConfigJSContent:var_-80] retain];
    var_-120 = [[var_-72 h5AlipayBridgeStartupParamsJSContent:var_-80] retain];
    var_-112 = [[var_-72 h5AlipayBridgeJSContent:var_-80] retain];
    var_-104 = [[var_-72 h5BizlogPreContent] retain];
    var_-96 = [[var_-72 nbComponentJSContent] retain];
    var_-64 = r12;
    var_-88 = [[var_-72 keyBoardJsWithAppId:r12] retain];
    rax = [var_-72 passDataString:var_-80];
    rax = [rax retain];
    var_-184 = r15;
    rcx = r15;
    r11 = @"";
    if (r15 == 0x0) {
            r11 = @"";
            rcx = r11;
    }
    if (var_-160 == 0x0) {
            r11 = @"";
            r8 = r11;
    }
    if (var_-152 == 0x0) {
            r11 = @"";
            r9 = r11;
    }
    rdx = var_-144;
    if (rdx == 0x0) {
            r11 = @"";
            rdx = r11;
    }
    var_-72 = rdx;
    rdx = var_-136;
    if (rdx == 0x0) {
            r11 = @"";
            rdx = r11;
    }
    var_-176 = rdx;
    rbx = var_-120;
    if (rbx == 0x0) {
            r11 = @"";
            rbx = r11;
    }
    r14 = var_-112;
    if (r14 == 0x0) {
            r11 = @"";
            r14 = r11;
    }
    r10 = var_-128;
    if (r10 == 0x0) {
            r11 = @"";
            r10 = r11;
    }
    r15 = var_-104;
    if (r15 == 0x0) {
            r11 = @"";
            r15 = r11;
    }
    r12 = rax;
    var_-168 = rax;
    r13 = var_-96;
    if (r13 == 0x0) {
            r11 = @"";
            r13 = r11;
    }
    if (rax == 0x0) {
            r11 = @"";
            r12 = r11;
    }
    rax = var_-88;
    if (rax != 0x0) {
            r11 = rax;
    }
    rsp = (rsp - 0x50) + 0x50;
    r14 = [[NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@%@%@", rcx, r8, r9, stack[2048], stack[2049], stack[2050], stack[2051], stack[2052], stack[2053], stack[2054], stack[2055]] retain];
    [var_-168 release];
    [var_-88 release];
    [var_-96 release];
    [var_-104 release];
    [var_-112 release];
    [var_-120 release];
    [var_-128 release];
    [var_-136 release];
    [var_-144 release];
    [var_-152 release];
    [var_-160 release];
    [var_-184 release];
    [var_-64 release];
    [var_-80 release];
    if (*___stack_chk_guard == *___stack_chk_guard) {
            rax = [r14 autorelease];
    }
    else {
            rax = __stack_chk_fail();
    }
    return rax;
}

 

void -[Plugin4HandleProxyRequest responseH5JSBridgeWithEvent:](void * self, void * _cmd, void * arg2) {
    rax = [arg2 retain];
    rbx = rax;
    var_-48 = rax;
    rax = [arg2 customResponse];
    rax = [rax retain];
    [rax setHeader:@"X-LocalRes" value:@"1"];
    [rax release];
    r15 = [[self getInjectJSDataWithEvent:rbx] retain];
    rax = [arg2 customResponse];
    rax = [rax retain];
    [rax setHeader:@"Cache-Control" value:@"max-age=0, s-maxage=0, must-revalidate"];
    [rax release];
    r12 = [[arg2 customResponse] retain];
    rax = [r15 dataUsingEncoding:0x4];
    rax = [rax retain];
    [r12 respondWithData:rax mimeType:@"application/javascript"];
    [rax release];
    [r12 release];
    [arg2 preventDefault];
    [var_-48 release];
    [r15 release];
    return;
}

上面的respondWithData:rax,rax就是刚才的数据

void -[PSDResponse respondWithData:mimeType:statusCode:](void * self, void * _cmd, void * arg2, void * arg3, long long arg4) {
    r12 = arg4;
    r13 = self;
    var_-80 = [arg2 retain];
    r15 = [arg3 retain];
    if (*(int8_t *)(r13 + 0x10) == 0x0) {
            rax = [*(r13 + 0x8) objectForKeyedSubscript:@"Content-Type"];
            rax = [rax retain];
            [rax release];
            var_-64 = r12;
            if (rax == 0x0) {
                    if (r15 == 0x0) {
                            rax = objc_loadWeakRetained(r13 + 0x28);
                            var_-56 = rax;
                            rax = [rax request];
                            rax = [rax retain];
                            var_-48 = rax;
                            rax = [rax URL];
                            rax = [rax retain];
                            var_-72 = rax;
                            rax = [rax pathExtension];
                            rax = [rax retain];
                            r12 = rax;
                            rax = [r13 _mimeTypeOf:rax];
                            rax = [rax retain];
                            rdi = r15;
                            r15 = rax;
                            [rdi release];
                            [r12 release];
                            [var_-72 release];
                            [var_-48 release];
                            [var_-56 release];
                            if (r15 != 0x0) {
                                    [*(r13 + 0x8) setObject:r15 forKeyedSubscript:@"Content-Type"];
                            }
                            else {
                                    r15 = 0x0;
                            }
                    }
                    else {
                            [*(r13 + 0x8) setObject:r15 forKeyedSubscript:@"Content-Type"];
                    }
            }
            var_-56 = r15;
            rax = [*(r13 + 0x8) objectForKeyedSubscript:@"Content-Length"];
            rax = [rax retain];
            [rax release];
            if (rax == 0x0) {
                    rax = [r13 _contentLength:var_-80];
                    rax = [rax retain];
                    [*(r13 + 0x8) setObject:rax forKeyedSubscript:@"Content-Length"];
                    [rax release];
            }
            rbx = [NSURLCustomResponse alloc];
            var_-48 = r13 + 0x28;
            rax = objc_loadWeakRetained(r13 + 0x28);
            r14 = rax;
            rax = [rax request];
            rax = [rax retain];
            r15 = rax;
            rax = [rax URL];
            rax = [rax retain];
            var_-72 = r13;
            rcx = var_-64;
            var_-64 = [rbx initWithURL:rax statusCode:rcx HTTPVersion:@"HTTP/1.1" headerFields:*(r13 + 0x8)];
            [rax release];
            [r15 release];
            [r14 release];
            r15 = var_-56;
            [r15 rangeOfString:@";"];
            if (@";" != 0x0) {
                    rbx = [[r15 substringToIndex:[r15 rangeOfString:@";", rcx, @"HTTP/1.1"], rcx, @"HTTP/1.1"] retain];
                    [r15 release];
                    r15 = rbx;
            }
            [var_-64 setCustomMIMEType:r15, rcx, @"HTTP/1.1"];
            rbx = [objc_loadWeakRetained(var_-48) retain];
            rax = objc_loadWeakRetained(var_-48);
            r14 = rax;
            rax = [rax request];
            rax = [rax retain];
            [rbx PSDWebViewURLProtocol:rbx startLoading:rax, @"HTTP/1.1"];
            [rbx release];
            [rax release];
            [r14 release];
            [rbx release];
            rbx = objc_loadWeakRetained(var_-48);
            [rbx PSDWebViewURLProtocol:rbx didReceiveResponse:var_-64 cacheStoragePolicy:*(var_-72 + 0x20)];
            [rbx release];
            rax = objc_loadWeakRetained(var_-48);
            [rax PSDWebViewURLProtocol:rax didLoadData:var_-80, *(var_-72 + 0x20)];
            [rax release];
            r15 = r15;
            rax = objc_loadWeakRetained(var_-48);
            [rax PSDWebViewURLProtocolDidFinishLoading:rax, var_-80, *(var_-72 + 0x20)];
            [rax release];
            [var_-64 release];
    }
    [r15 release];
    [var_-80 release];
    return;
}

应该是 [rax PSDWebViewURLProtocol:rax didLoadData:var_-80, *(var_-72 + 0x20)];返回了

注意:不是- (void)connection:(NSURLConnection *)connection didReceiveDataS:(NSData *)data

 

上面这些的前提是加载https://xalipaynebula/xalipaynebulabridge/xalipaynebulabridge.js?q=105553122741504这个请求

拼接参数ALIPAYH5STARTUPPARAMS               

      

替换 PSDWebViewURLProtocol的- (void)PSDWebViewURLProtocol:(id)arg1 didLoadDataS:(id)arg2;

加载这个请求后的数据可以截取到


"use strict";
(function (window) {
    function call() {
        var a = arguments,
                fn = function () {
                    window.AlipayJSBridge.call.apply(null, a);
                };

        window.AlipayJSBridge ? fn() : document.addEventListener('AlipayJSBridgeReady', fn, false);
    }
    window.navigator.geolocation.getCurrentPosition = function (cb) {
 call('getLocation', {requestType: 2}, function (rtv) {
            var pos = {
                coords: {
                    accuracy: 50,
                    altitude: null,
                    altitudeAccuracy: null,
                    heading: null,
                    latitude: null,
                    longitude: null,
                    speed: null
                },
                timestamp: (+new Date())
            };
            for (var k in rtv) {
                if (rtv.hasOwnProperty(k)) {
                    pos.coords[k] = rtv[k];
                }
            }
            cb && cb(pos);
        });
    };
})(window);
//rwrite pushState and replaceState to trigger change
(function(){
  try{
    window.history.pushState = (function(fn){
      return function(){
        var args = [].slice.call(arguments);
        document.addEventListener("AlipayJSBridgeReady",function(){
          window.AlipayJSBridge.call("pushStateChange",{});
        },false);
        fn.apply(this,args);
      }
    })(window.history.pushState);

    window.history.replaceState = (function(fn){
      return function(){
        var args = [].slice.call(arguments);
        document.addEventListener("AlipayJSBridgeReady",function(){
          window.AlipayJSBridge.call("pushStateChange",{});
        },false);
        fn.apply(this,args);
      }
    })(window.history.replaceState);
  }catch(ex){

  }
})();
window.H5Performance={timing:{requestStart:1604048191872,responseEnd:1604048191888}};(window.AlipayH5Performance && !window.AlipayCallFromJS) || (function(){
    if (navigator.userAgent.indexOf(' AlipayClient/') < 0) {
        return;
    }

    /***************Messge Handler*****************/
    var safeCallMessage,shouldUseMessageChannel = false;
    if (window.webkit
        && window.webkit.messageHandlers
        && window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER
        && window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER.postMessage) {
        var webkit = window.webkit;
        var postMessage = window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER.postMessage;
        var PSDBRIDGEMESSAGEHANDLER = window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER;
        safeCallMessage = function(message){
            return postMessage.apply(PSDBRIDGEMESSAGEHANDLER,[message]);
        }
        shouldUseMessageChannel = true;
    }

    /***************monitorKernel*****************/
    var iframe = {};
    var sendMessageQueue={};
    var timerHandler={};
    function type(obj) {
        return Object.prototype.toString.call(obj).replace(/\[object (\w+)\]/, '$1').toLowerCase();
    }
    var monitorKernel={
        init:function(){
            this.init=null;
            this.renderIframe();
            this.monitorDOMReady();
            this.monitorPageLoad();
            this.monitorJSErrors();
            this.monitorDNSTime();
            this.monitorCacheRate();
            this.monitorMixedContent();
        },
        monitorDOMReady:function(){
            var t=this;
            var readyRE = /complete|loaded|interactive/;
            if (readyRE.test(document.readyState)) {
                t.pushMessage('monitor',{
                    name:'domReady',
                    value:new Date().getTime(),
                    extra:'completed'
                });
                t.sendSignal();
            } else {
                document.addEventListener("DOMContentLoaded", function(event) {
                    t.pushMessage('monitor',{
                        name:'domReady',
                        value:new Date().getTime(),
                        extra:'complete'
                    });
                    t.sendSignal();
                },true);
            }
        },
        monitorPageLoad:function(){
            var t=this;
            window.addEventListener("load", function(event) {
                t.pushMessage('monitor',{
                    name:'pageLoad',
                    value:new Date().getTime(),
                    extra:'load'
                });
                t.sendSignal();
            },true);
        },
        monitorJSErrors:function(){
            var t=this;
            window.addEventListener("error", function(event) {
                if (event.message) {
                    t.pushMessage('monitor',{
                                  name:'jsErrors',
                                  value:event.message,
                                  filename:event.filename,
                                  lineno:event.lineno,
                                  colno:event.colno
                                  });
                    t.sendSignal();
                }
            },true);
            var unhandledrejection_handler = function(event) {
                if (event.reason) {
                    var error = event.reason;
                    if (typeof(event.reason) === 'object') {
                         try {
                             error =JSON.stringify(event.reason);
                         } catch (ex) { }
                     }

                    t.pushMessage('monitor', {
                        name: 'jsErrors',
                        value: 'Unhandled Promise Rejection:' + error,
                        filename: location.href.split("?")[0]
                    });
                    t.sendSignal();
                }
            }

            if (typeof PromiseRejectionEvent !== 'undefined') {
                window.addEventListener("unhandledrejection",
                function(event) {
                    unhandledrejection_handler(event);
                },
                false);
            } else {
                var oldHandler = window['onunhandledrejection'];
                window['onunhandledrejection'] = function(event) {
                    try {
                        oldHandler(event);
                    } catch(ex) {}
                    unhandledrejection_handler(event);
                };
            }
        },
        monitorDNSTime:function(){
            var t=this;
            window.addEventListener("load", function(event) {
                if(window.performance && window.performance.timing && window.performance.timing.domainLookupEnd-window.performance.timing.domainLookupStart){
                    t.pushMessage('monitor',{
                        name:'dns',
                        value:window.performance.timing.domainLookupEnd-window.performance.timing.domainLookupStart,
                        extra:'support'
                    });
                }else{
                    t.pushMessage('monitor',{
                        name:'dns',
                        value:'',
                        extra:'notsupport'
                    });
                }
                t.sendSignal();
            },true);
        },
        monitorMixedContent:function(){
            var t=this;
            var errorArr=[];
            var readyRE = /complete|loaded|interactive/;
            if (readyRE.test(document.readyState)) {
                window.location.protocol == 'https:' && [].slice.call(document.querySelectorAll('link[rel=stylesheet][href^="http:"], script[src^="http:"]')).forEach(function (elem) {
                    errorArr.push(elem.tagName + ':' + (elem.src || elem.href));
                });
                if(errorArr.length>0){
                    t.pushMessage('monitor',{
                        name:'mixedContent',
                        value:errorArr.join('@|@')
                    });
                    t.sendSignal();
                }
            } else {
                document.addEventListener("DOMContentLoaded", function(event) {
                    window.location.protocol == 'https:' && [].slice.call(document.querySelectorAll('link[rel=stylesheet][href^="http:"], script[src^="http:"]')).forEach(function (elem) {
                        errorArr.push(elem.tagName + ':' + (elem.src || elem.href));
                    });
                    if(errorArr.length>0){
                        t.pushMessage('monitor',{
                            name:'mixedContent',
                            value:errorArr.join('@|@')
                        });
                        t.sendSignal();
                    }
                },true);
            }
        },
        monitorCacheRate:function(){
            var t=this,
                result={
                    name:'cacheRate'
                },resourceArr;
            window.addEventListener("load", function(event) {
                if(window.performance && typeof window.performance.getEntriesByType ==='function' && (resourceArr=window.performance.getEntriesByType("resource"))){
                    if(resourceArr.length>0){
                        var cacheCount=0;
                        for(var i=0;i<resourceArr.length;i++){
                            if(resourceArr[i].duration===0){
                                cacheCount++;
                            }
                        }
                        result.value=(cacheCount/resourceArr.length).toFixed(4);

                    }else{
                        result.value=0.0000;
                    }
                    result.extra='support';
                }else{
                    result.value='';
                    result.extra='notsupport';
                }
                t.pushMessage('monitor',result);
                t.sendSignal();
            },true);
        },
        sendSignal:function(timer,tag){
            if (shouldUseMessageChannel) {
                setTimeout(function(){
                    safeCallMessage({
                        queue:AlipayH5Performance.fetchMessageQueue(),
                        type:"monitor"
                    });
                },0);
            }else{
                timer = (typeof timer=='number' &&timer>=0)?timer:500;
                tag = tag || 'monitor';
                clearTimeout(timerHandler[tag]);
                timerHandler[tag]=setTimeout(function(){
                    if (!(iframe && iframe[tag])){
                        monitorKernel.renderIframe(tag);
                    }
                    if (iframe[tag]) {
                        iframe[tag].src='alipay'+tag.toLowerCase()+'://dispatch_'+tag.toLowerCase()+'_message';
                    }
                },timer);
            }
        },
        renderIframe:function(tag) {
            tag = tag || 'monitor';
            if ((iframe && iframe[tag]) || shouldUseMessageChannel) return;
            try {
                var iframeElement = document.createElement("iframe");
                iframeElement.id = "__AlipayH5"+tag+"Iframe";
                iframeElement.style.display = "none";
                if (document.documentElement) {
                    document.documentElement.appendChild(iframeElement);
                }else{
                    //for pdf file
                    document.appendChild(iframeElement);
                }
                iframe[tag] = iframeElement;
            } catch (e) {}
        },
        pushMessage:function(tag,obj){
            tag = tag || 'monitor';
            if(!(sendMessageQueue && type(sendMessageQueue[tag]) == 'array')){
                sendMessageQueue[tag] = [];
            }
            sendMessageQueue[tag].push(obj);

        },
        getMessage:function(tag){
            tag = tag || 'monitor';
            if(!(sendMessageQueue && type(sendMessageQueue[tag]) == 'array')){
                sendMessageQueue[tag] = [];
            }
            var messageQueueString = JSON.stringify(sendMessageQueue[tag]);
            sendMessageQueue[tag] = [];
            return messageQueueString;

        }
    }
    monitorKernel.init();
    if (window.AlipayJSBridge) {
        monitorKernel.pushMessage('monitor',{name: 'bridgeReady',value: Date.now() + ''});
        monitorKernel.sendSignal(0);
    } else {
        document.addEventListener('AlipayJSBridgeReady', function(){
            monitorKernel.pushMessage('monitor',{name: 'bridgeReady',value: Date.now() + ''});
            monitorKernel.sendSignal(0);
        }, false);
    }
    var monitorInterface={
        fetchMessageQueue: function (tag) {
            return monitorKernel.getMessage(tag);
        },
        reportBizReady: function(){
            monitorKernel.pushMessage('monitor',{name: 'availableTime',value: Date.now() + ''});
            monitorKernel.sendSignal(0);
        },
        pushMessage:function(tag,obj){
            monitorKernel.pushMessage(tag,obj);
        },
        addTrackData:function(obj,tag){
            tag = tag || 'monitor';
            if(obj.value){
                obj.value+=('|time='+new Date().getTime());
            }
            monitorKernel.pushMessage(tag,obj);
            monitorKernel.sendSignal(0);
        },
        addTimeReport:function(obj){
            var objStr = '';
            for(var item in obj){
                objStr += (((objStr=='')?'':'&')+item+'='+obj[item]);
            }
            monitorInterface.addTrackData({
                'name':'timeReport',
                'value':objStr
            });
        },
        sendSignal:function(tag){
            monitorKernel.renderIframe(tag);
            monitorKernel.sendSignal(0,tag);
        },
        version:'1.2'
    }
    window.AlipayH5Performance = monitorInterface;
})();
(window.AlipayH5Report && !window.AlipayCallFromJS) || (function(){
    if (navigator.userAgent.indexOf(' AlipayClient/') < 0) {
        return;
    }
    var monitorInterface={
        fetchMessageQueue: function (tag) {
            return window.AlipayH5Performance.fetchMessageQueue('report');
        }
    }
    window.AlipayH5Report = monitorInterface;
})();
(window.AlipayH5Share && !window.AlipayCallFromJS) || (function() {
  var AlipayH5Share = {};
  var shareMessage = {
    title: "",
    imgUrl: "",
    link:"",
    desc: "",
    fromMeta: false,
    ready: false
  };
  var collectReadyState = {
    title: false,
    link:false,
    imgUrl: false,
    desc: false
  };

  var imgArr;
  var H5ShareCollector = {
    init: function(strict) {
      var t = this;
      t.strict = (typeof strict ==='undefined')?true:(!!strict);
      t.collectLink();
      t.collectTitle();
      t.collectDesc();
      t.collectThumbnail();
    },
    collectLink:function(){
      var t=this;
      var metaLinkNode = document.querySelector('meta[name="Alipay:link"]');
      if (metaLinkNode && metaLinkNode.getAttribute("content")) {
        shareMessage.fromMeta = true;
        shareMessage.link = metaLinkNode.getAttribute("content");
      }
      collectReadyState.link = true;
      t.collectReady();
    },
    collectTitle: function() {
      var t = this;
      var metaTitleNode = document.querySelector('meta[name="Alipay:title"]');
      if (metaTitleNode && metaTitleNode.getAttribute("content")) {
        collectReadyState.title = true;
        shareMessage.title = metaTitleNode.getAttribute("content");
        shareMessage.fromMeta = true;
        t.collectReady();
      } else if(window.location.hostname==='mp.weixin.qq.com'  && typeof msg_title !== "undefined" && msg_title) {
          collectReadyState.title = true;
          shareMessage.title = t.htmlDecode(msg_title);
          t.collectReady();
      } else{
        if (document.title && document.title.trim() !== "") {
          shareMessage.title = t.contentTidy(document.title);
          collectReadyState.title = true;
          t.collectReady();
        } else {
          if (document.getElementsByTagName("H1").length > 0 && document.getElementsByTagName("H1")[0].textContent.length > 0) {
            var tmpH1 = t.nodeStrFliter(document.getElementsByTagName("H1")[0]);
            if (t.getStrLen(tmpH1) <= 64 && tmpH1.length > 0) {
              shareMessage.title = tmpH1;
              collectReadyState.title = true;
              t.collectReady();
            }
          }
        }
      }
    },
    collectThumbnail: function() {
      var t = this;
      var metaImgNode = document.querySelector('meta[name="Alipay:imgUrl"]');
      if (metaImgNode && metaImgNode.getAttribute("content")) {
        collectReadyState.imgUrl = true;
        shareMessage.imgUrl = t.getAbsoluteUrl(metaImgNode.getAttribute("content"));
        shareMessage.fromMeta = true;
        t.collectReady();
      } else if(window.location.hostname==='mp.weixin.qq.com'  && typeof msg_cdn_url !== "undefined"  && msg_cdn_url.match(/^http(s?):\/\/.*$/g)) {
        collectReadyState.imgUrl = true;
        shareMessage.imgUrl = msg_cdn_url;
        t.collectReady();
      } else {
        collectReadyState.imgUrl = false;
        t.collectReady();
        imgArr = Array.prototype.slice.call(document.images);
        t.findImgUrl(200*50,2000*640);
        if(!t.strict){
          if(shareMessage.imgUrl == ''){
            t.findImgUrl(100*25,200*50);
          }
          if(shareMessage.imgUrl == ''){
            t.findImgUrl(32*32,100*25);
          }
        }
        if(shareMessage.imgUrl == ''){
          var iconImgNode = document.querySelector('link[type="image/x-icon"]');
          if (iconImgNode && iconImgNode.getAttribute("href")) {
            collectReadyState.imgUrl = true;
            shareMessage.imgUrl = t.getAbsoluteUrl(iconImgNode.getAttribute("href"));
            t.collectReady();
          }
        }
      }
    },
    findImgUrl: function(min,max) {
      var t = H5ShareCollector;
      if (imgArr.length === 0) {
        collectReadyState.imgUrl = true;
        t.collectReady();
        return;
      }
      var imgYAxis = 99999;
      var imgXAxis = 99999;
      if (imgArr.length > 0 && !collectReadyState.imgUrl) {
        for (var i = 0; i < imgArr.length; i++) {
          var curImg = imgArr[i];
          if(t.isHidden(curImg)){
            continue;
          }
          if(t.isBanner(curImg)){
            continue;
          }
          if(t.isBase64(curImg)){
            continue;
          }
          if (curImg.complete || curImg.natureWidth) {
            if ((curImg.naturalHeight * curImg.naturalWidth >= min && curImg.naturalHeight * curImg.naturalWidth < max)) {
              if ((curImg.y > 60 && curImg.y <imgYAxis) || (curImg.y <= 60 && curImg.y >imgYAxis) || (curImg.y ===imgYAxis && curImg.x <imgXAxis)) {
                shareMessage.imgUrl = curImg.src;
                imgYAxis = curImg.y || 0;
                imgXAxis = curImg.x || 0;
                collectReadyState.imgUrl = true;
                t.collectReady();
              }
            }
          }
        }
      }

    },
    collectDesc: function() {
      var t = this;
      var metaDescNode = document.querySelector('meta[name="Alipay:desc"]');
      if (metaDescNode && metaDescNode.getAttribute("content")) {
        collectReadyState.desc = true;
        shareMessage.desc = metaDescNode.getAttribute("content");
        shareMessage.fromMeta = true;
        t.collectReady();
      }

      if(!collectReadyState.desc && window.location.hostname==='mp.weixin.qq.com' && typeof msg_desc !== "undefined" && msg_desc) {
        collectReadyState.desc = true;
        shareMessage.desc = t.htmlDecode(msg_desc);
        t.collectReady();
      }

      if (!collectReadyState.desc) {
        t.tarvelPtags(50,2000);
      }
      if (!collectReadyState.desc) {
        t.tarvelPtags(20,50);
      }
      if (!collectReadyState.desc) {
        t.travelDocument(document.body,50,2000);
      }
      if (!collectReadyState.desc) {
        var descNode = document.querySelector('meta[name="description"]');
        if (descNode && descNode.getAttribute("content")) {
          shareMessage.desc = t.contentTidy(descNode.getAttribute("content"));
          shareMessage.fromMeta = true;
          collectReadyState.desc = true;
          t.collectReady();
        }
      }
      if(!t.strict){
        if (!collectReadyState.desc) {
          t.travelDocument(document.body,20,50);
        }
        if (!collectReadyState.desc) {
          t.tarvelPtags(10,20);
        }
        if (!collectReadyState.desc) {
          t.travelDocument(document.body,10,20);
        }
      }
      if (!collectReadyState.desc){
        var hostDesc = window.location.hostname;
        if(hostDesc != undefined && hostDesc != ''){
          shareMessage.desc = hostDesc;
          collectReadyState.desc = true;
          t.collectReady();
        }
      }
      var shareHref=window.location.href;
      var shareDesc = shareMessage.desc?shareMessage.desc:'';
      var shareLeaveLength= 280 - t.getStrLen(shareHref);
      // 如果剩余长度,大于摘要长度,则截取摘要
      if(shareLeaveLength <= t.getStrLen(shareDesc) && shareLeaveLength>=0){
        shareDesc = t.cutStr(shareDesc,Math.floor(shareLeaveLength/2));
      }
      shareMessage.desc = shareDesc;
    },
    collectReady: function() {
      if (collectReadyState.title && collectReadyState.imgUrl  && collectReadyState.link && collectReadyState.desc) {
        shareMessage.ready = true;
      }
    },
    tarvelPtags:function(min,max){
      var t=this;
      var pArr = Array.prototype.slice.call(document.getElementsByTagName("P"));
      if (pArr.length > 0) {
        for (var i = 0; i < pArr.length; i++) {
          var c=pArr[i];
          if(typeof c ==='undefined'){
            continue;
          }
          if (c.id == "Debug") {
            continue;
          }
          if(t.isHidden(c)){
            continue;
          }
          var pConetent=c.textContent;
          if (t.getStrLen(pConetent) >= min && t.getStrLen(pConetent) < max) {
            pConetent = t.nodeStrFliter(c, false);
          }
          if (t.getStrLen(pConetent) >= min && t.getStrLen(pConetent) < max) {
            shareMessage.desc = pConetent;
            collectReadyState.desc = true;
            t.collectReady();
          }
          if(collectReadyState.desc){
            break;
          }
        }
      }
    },
    travelDocument: function(el,min,max) {
      if(el !=undefined && el.hasChildNodes()){
        var t = this,
          childNodes = el.childNodes;
        if (childNodes && childNodes.length > 0) {
          for (var i = 0; i < childNodes.length; i++) {
            var c = childNodes[i];
            if(typeof c ==='undefined'){
              continue;
            }
            switch (c.nodeType) {
              case 1:
                if(!t.isHidden(c)){
                  if (c.nodeName != "P" && c.nodeName != "SCRIPT" && c.nodeName != "STYLE" && c.nodeName != "AUDIO" && c.nodeName != "VIDEO") {
                    t.travelDocument(c,min,max);
                  }
                }
                break;
              case 3:
                var tmp = c.nodeValue;
                if (t.getStrLen(tmp) >= min && t.getStrLen(tmp) < max) {
                  tmp = t.contentTidy(tmp);
                }
                if (t.getStrLen(tmp) >= min && t.getStrLen(tmp) <= max) {
                  shareMessage.desc = tmp;
                  collectReadyState.desc = true;
                  t.collectReady();
                }
                break;
            }
            if (collectReadyState.desc) {
              break;
            }
          }
        }
      }
    },
    getStrLen: function(str) {
      return str.replace(/[^\x00-\xff]/g, "xx").length;
    },
    cutStr:function(str, len){
      var char_length = 0;
      for (var i = 0; i < str.length; i++){
        var son_str = str.charAt(i);
        encodeURI(son_str).length > 2 ? char_length += 1 : char_length += 0.5;
        if (char_length >= len){
          var sub_len = char_length == len ? i+1 : i;
          return str.substr(0, sub_len);
          break;
        }
      }
    },
    getAbsoluteUrl:function (url) {
      var a = document.createElement('A');
      a.href = url;  // 设置相对路径给Image, 此时会发送出请求
      url = a.href;  // 此时相对路径已经变成绝对路径
      return url;
    },
    getCurrentStyle:function(obj, prop) {
      if (window.getComputedStyle) {
        return window.getComputedStyle(obj,null).getPropertyValue(prop);
      }else if (obj.currentStyle) {
        return obj.currentStyle[prop];
      }
      return null;
    },
    isHidden:function(el){
      var t = H5ShareCollector;
      var isHidden =  ( el != undefined && el.nodeType != undefined && el.nodeType == '1') && (t.getCurrentStyle(el,'display')=='none' || t.getCurrentStyle(el,'visibility')=='hidden');
      if(isHidden){
        return true;
      }else{
        return el.parentNode != undefined ?t.isHidden(el.parentNode):false;
      }
    },
    isBanner:function(el){
      var t = H5ShareCollector;
      var isBanner =  ( el != undefined && el.nodeType != undefined && el.nodeType == '1') && t.matchKeyword([el.className,el.id],['banner','baner']);
      if(isBanner){
        return true;
      }else{
        return el.parentNode != undefined ?t.isBanner(el.parentNode):false;
      }
    },
    isBase64:function(el){
      var t = H5ShareCollector;
      var isBase64 =  ( el != undefined && el.nodeType != undefined && el.nodeType == '1') && el.src.indexOf("http")!== 0;
      if(isBase64){
        return true;
      }else{
        return el.parentNode != undefined ?t.isBanner(el.parentNode):false;
      }
    },
    matchKeyword:function(srcArr,targetArr){
      srcArr = srcArr || [];
      targetArr = targetArr || [];
      for(var i=0;i<srcArr.length;i++){
        for(var j=0;j<targetArr.length;j++){
          if ((srcArr[i] || '').indexOf(targetArr[j])>-1) {
            return true;
            break;
          }
        }
      }
      return false;
    },
    getType:function(obj) {
      return Object.prototype.toString.call(obj).replace(/\[object (\w+)\]/, '$1').toLowerCase();
    },
    htmlDecode: function(str) {
      var t = document.createElement("div");
      t.innerHTML = str;
      return t.innerText || t.textContent
    },
    nodeStrFliter: function(element, imgAlt) {
      imgAlt = imgAlt || true;
      var t = this,
        tmp = element.cloneNode(true);
      if (imgAlt) {
        Array.prototype.forEach.call(tmp.querySelectorAll("img[alt]"), function(el) {
          el.parentNode.replaceChild(document.createTextNode(el.alt), el);
        });
      }
      Array.prototype.forEach.call(tmp.querySelectorAll("script,style,link"), function(el) {
        el.parentNode.replaceChild(document.createTextNode(""), el);
      });
      tmp = t.contentTidy(tmp.textContent);
      return tmp;
    },
    contentTidy: function(str) {
      return str.replace(/\s{4}/g, " ").replace(/(\r|\n)/g, "").trim();
    }
  };
  AlipayH5Share.getShareContent = function(strict) {
    strict = (typeof strict ==='undefined')?true:(!!strict);
    H5ShareCollector.init(strict);
    return JSON.stringify(shareMessage);
  };
    document.addEventListener("JSPlugin_AlipayH5Share", function(e) {
        var strict = (typeof e.strict ==='undefined')?true:(!!e.strict);
        if (window.AlipayJSBridge && e.clientId) {
            H5ShareCollector.init(strict);
            if (window.AlipayJSBridge && e.clientId) {
                setTimeout(function(){
                    H5ShareCollector.init(strict);
                    AlipayJSBridge.callback(e.clientId, shareMessage);
                },0);
            }
            AlipayJSBridge.callback(e.clientId, shareMessage);
        }
    });
    window.AlipayH5Share = AlipayH5Share;
})();
window.H5PSDAccessType='remote';window.ALIPAYH5STARTUPPARAMS={"appid":"201****************略

//contact with lin.weng@alipay.com  before change  this file
(window.AlipayJSBridge && !window.AlipayCallFromJS)|| (function () {
    var msgTKTarget = 'c634be78b2c193a11e8758da9cac1d2b'; var shouldUseTK = false; if(shouldUseTK && window != top){return;};
    var iframe = null;

    var rawJsonStringify = JSON.stringify;
    var rawJsonParse = JSON.parse;
    var rawArrayPush = Array.prototype.push;
    /***************Messge Handler*****************/
    var safeCallMessage,shouldUseMessageChannel = false;
    if (window.webkit
        && window.webkit.messageHandlers
        && window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER
        && window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER.postMessage) {
        var webkit = window.webkit;
        var postMessage = window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER.postMessage;
        var PSDBRIDGEMESSAGEHANDLER = window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER;
        window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER.postMessage = function(){};
        safeCallMessage = function(message){
            return postMessage.apply(PSDBRIDGEMESSAGEHANDLER,[message]);
        }
        shouldUseMessageChannel = true;
    }

    function renderIframe() {
        if (iframe || shouldUseMessageChannel) return;
        try {
            iframe = document.createElement("iframe");
            iframe.id = "__AlipayJSBridgeIframe";
            iframe.style.display = "none";
            if (document.documentElement) {
                document.documentElement.appendChild(iframe);
            }else{
                //for pdf to append iframe
                document.appendChild(iframe);
            }
        } catch (e) {

        }
    }

    function onDOMReady(callback) {
        var readyRE = /complete|loaded|interactive/;
        if (readyRE.test(document.readyState)) {
            setTimeout(function() {
                       callback();
                       }, 1);
        } else {
            document.defaultView.addEventListener('DOMContentLoaded', function () {
                callback();
            }, false);
        }
    }

    /***************Param Type*****************/
    var NEBULA_TYPE_INFO = "NEBULATYPEINFO",NEBULA_TYPE_OF_ARRAYBUFFER = "ArrayBuffer";

    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var lookup = new Uint8Array(256);
    for (var i = 0; i < chars.length; i++) {
        lookup[chars.charCodeAt(i)] = i;
    }
    
    function arrayBufferToBase64(buffer) {
        var binary = '';
        var bytes = new Uint8Array(buffer);
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
    }

    function base64ToArrayBuffer(base64) {
        var bufferLength = base64.length * 0.75,
        len = base64.length, i, p = 0,
        encoded1, encoded2, encoded3, encoded4;

        if (base64[base64.length - 1] === "=") {
          bufferLength--;
          if (base64[base64.length - 2] === "=") {
            bufferLength--;
          }
        }

        var arraybuffer = new ArrayBuffer(bufferLength),
        bytes = new Uint8Array(arraybuffer);

        for (i = 0; i < len; i+=4) {
          encoded1 = lookup[base64.charCodeAt(i)];
          encoded2 = lookup[base64.charCodeAt(i+1)];
          encoded3 = lookup[base64.charCodeAt(i+2)];
          encoded4 = lookup[base64.charCodeAt(i+3)];

          bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
          bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
          bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
        }

        return arraybuffer;
    }

    function transformCallParam(param){
        var result = param;
        for(var key in param){
            if (param.hasOwnProperty(key)) {
                var val = param[key];
                if (val instanceof ArrayBuffer) {
                    param[key] = arrayBufferToBase64(val);
                    if (!result[NEBULA_TYPE_INFO]) {
                        result[NEBULA_TYPE_INFO] = {};
                    }
                    result[NEBULA_TYPE_INFO][key] = {"type" : NEBULA_TYPE_OF_ARRAYBUFFER};
                }
            }
        }
        return result;
    }

    function transformResponseData(responsedata){
        if (responsedata && responsedata[NEBULA_TYPE_INFO]) {
            var nebulaTypeInfo = responsedata[NEBULA_TYPE_INFO];
            if (nebulaTypeInfo) {
                for(var key in nebulaTypeInfo){
                    if (nebulaTypeInfo.hasOwnProperty(key)) {
                        var item = nebulaTypeInfo[key];
                        if (item.type) {
                            var typeVal = item["type"];
                            if (typeVal === NEBULA_TYPE_OF_ARRAYBUFFER) {
                                responsedata[key] = base64ToArrayBuffer(responsedata[key]);
                            }
                        }
                    }
                }
                delete responsedata[NEBULA_TYPE_INFO];
            }
        }
        return responsedata;
    }

    /***************Bridge*****************/
    var msgKt = "messageTK";
    var callbackPoll = {};

    var sendMessageQueue = [];
    var receiveMessageQueue = [];

    var JSAPI = {
        /*
         * 调用Native功能
         */
        call: function (func, param, callback) {
            //jsbridge注入提前后,DOM环境可能还没创建,原jsbridge注入的同时创建iframe的方式将创建失败,改为调用接口的时候创建iframe
            //如果直接使用JSC通信
            renderIframe();
            //
            if ('string' !== typeof func) {
                return;
            }

            if ('function' === typeof param) {
                callback = param;
                param = null;
            } else if (typeof param !== 'object') {
                param = null;
            }

            // 防止时间戳重复
            var callbackId = func + '_' + new Date().getTime() + (Math.random());
            if ('function' === typeof callback) {
                callbackPoll[callbackId] = callback;
            }

            if (param && param.callbackId) {
                // 从Native调用过来的请求,再回调到Native的callback里
                // TODO: 需要优化,这里调用回Native的callback不需要传入`handlerName`
                func = {
                    responseId: param.callbackId,
                    responseData: param
                };
                delete param.callbackId;
            } else {
                // 从页面直接发起到Native的请求
                // 支持arrayBuffer的数据格式
                func = {
                    handlerName: func,
                    data: transformCallParam(param) || {}
                };
                func.callbackId = '' + callbackId;
            }

//            //console.log('bridge.call: ' + JSON.stringify(func));

            rawArrayPush.call(sendMessageQueue, func);
            //use jsc
            if (window.AlipayCallFromJS && 'function' === typeof window.AlipayCallFromJS) {
                window.AlipayCallFromJS(JSAPI._fetchQueue(), document.location.href);
            }else if(window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER && window.webkit.messageHandlers.PSDBRIDGEMESSAGEHANDLER.postMessage){
                //use wkwebview message channel
                safeCallMessage({
                    type:"api",
                    queue:JSAPI._stringifyMessageQueue(),
                    msgKt:msgTKTarget
                });
            }else if (iframe) {
                iframe.src = "alipaybridge://dispatch_message";
            }
        },

        trigger: function (name, data) {
//            //console.log('bridge.trigger ' + name);
            if (name) {
                var triggerEvent = function (name, data) {
                    var callbackId;
                    if (data && data.callbackId) {
                        callbackId = data.callbackId;
                        data.callbackId = null;
                    }
                    var evt = document.createEvent("Events");
                    evt.initEvent(name, false, true);
                    evt.syncJsApis = [];

                    if (data) {
                        if (data.__pull__) {
                            delete data.__pull__;
                            for (var k in data) {
                                evt[k] = data[k];
                            }
                        } else {
                            evt.data = data;
                        }
                    }
                    var canceled = !document.dispatchEvent(evt);
                    if (callbackId) {
                        var callbackData = {};
                        callbackData.callbackId = callbackId;
                        callbackData[name + 'EventCanceled'] = canceled;
                        callbackData['syncJsApis'] = evt.syncJsApis;
                        JSAPI.call('__nofunc__', callbackData);
                    }
                };
                setTimeout(function () {
                    triggerEvent(name, data);
                }, 1);
            }
        },

        /*
         * Native调用js函数,传输消息
         **/
        _invokeJS: function (resp) {
//            //console.log('bridge._invokeJS: ' + resp);
            resp = rawJsonParse(resp);

            if (resp.responseId) {
                var func = callbackPoll[resp.responseId];
                //某些情况需要多次回调,添加keepCallback标识,防删除
                if (!(typeof resp.keepCallback == 'boolean' && resp.keepCallback)) {
                    delete callbackPoll[resp.responseId];
                }

                if ('function' === typeof func) {
                    // 避免死锁问题
                    setTimeout(function () {
                        func(transformResponseData(resp.responseData));
                    }, 1);
                }
            } else if (resp.handlerName) {
                if (resp.callbackId) {
                    resp.data = resp.data || {};
                    resp.data.callbackId = resp.callbackId;
                }
                JSAPI.trigger(resp.handlerName, resp.data);
            }
        },

        // ***********************************************
        // WebViewJSBridge.js库兼容 @远尘 2014.2.28

        _handleMessageFromObjC: function (message) {
            if (receiveMessageQueue&&!window.AlipayJSBridge) {
                receiveMessageQueue.push(message);
            } else {
                JSAPI._invokeJS(message);
            }
        },
        _stringifyMessageQueue:function(){
            var messageQueueString = rawJsonStringify(sendMessageQueue);
            sendMessageQueue = [];
            return messageQueueString;
        },
        _fetchQueue: function (tk) {
            //if shouldshouldUseTK  and if no token  we think it is illegal call and just retrun empth array
            if (shouldUseTK) {
                if (tk && msgTKTarget && msgTKTarget === tk) {
                    return JSAPI._stringifyMessageQueue();
                }else {
                    return '[]';
                }
            }else{
                return JSAPI._stringifyMessageQueue();
            }
        }
    };

    // ***********************************************

    // 初使化事件, 在webview didFinishLoad后调用
    JSAPI.init = function () {
        // dont call me any more
        //JSAPI.init = null;

                
        var readyEvent = document.createEvent('Events');
        readyEvent.initEvent('AlipayJSBridgeReady', false, false);

        // 处理ready事件发生以后才addEventListener的情况
        var docAddEventListener = document.addEventListener;
        document.addEventListener = function (name, func) {
            if (name === readyEvent.type) {
                // 保持func执行的异步性
                setTimeout(function () {
                    func(readyEvent);
                }, 1);
            } else {
                docAddEventListener.apply(document, arguments);
            }
        };

        document.dispatchEvent(readyEvent);

        var receivedMessages = receiveMessageQueue;
        receiveMessageQueue = null;
        for (var i = 0; i < receivedMessages.length; i++) {
            JSAPI._invokeJS(receivedMessages[i]);
        }
    };

    window.AlipayJSBridge = JSAPI;
    
    //动态替换js片段,为了解决在AlipayJSBridge Ready中,使用新增的js属性,由内核替换为js片段字符串
    "H5_BRIDGE_JS_***_REPLACE_STRING_***_SJ_EGDIRB_5H";

    //从全局对象中读取startupParams,确保ready中可用
    JSAPI.startupParams = window.ALIPAYH5STARTUPPARAMS || {};
                          
    //jsbridge提前后,将webViewDidFinishLoad中init方法,提前到DOMReady后执行,避免由于长时间加载资源,而影响到接口调用
    onDOMReady(JSAPI.init);

    onDOMReady(function(){
        if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.PSDBRIDGEDOMREADY && window.webkit.messageHandlers.PSDBRIDGEDOMREADY.postMessage) {
            window.webkit.messageHandlers.PSDBRIDGEDOMREADY.postMessage("");
        };
    });
})();
//if use WKScript to inject dynamic script,it will be fixed content,so we should do this on every pageloaded happen
(window.HASINJECTDRNAMICSCRIPT && !window.AlipayCallFromJS) || (function(){
    window.HASINJECTDRNAMICSCRIPT = false;
    function onDOMReady(callback) {
        var readyRE = /complete|loaded|interactive/;
        if (readyRE.test(document.readyState)) {
            setTimeout(function() {
                       callback();
                       }, 1);
        } else {
            document.defaultView.addEventListener('DOMContentLoaded', function () {
                callback();
            }, false);
        }
    }
    onDOMReady(function(){
               if (!window.HASINJECTDRNAMICSCRIPT) {
                 var jsArray = window.ALIPAYH5DYNAMICSCRIPT;
                 for (var i in jsArray) {
                 var jsSrc = jsArray[i];
                     if (jsSrc && /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/.test(jsSrc)){
                          var script,head = document.head || document.documentElement;
                          script=document.createElement("script");
                          script.async = true;
                          script.charset = "UTF-8";
                          script.src = jsSrc;
                          if(jsSrc.indexOf("nebula-addcors") > 0 ){
                            script.setAttribute('crossorigin','');
                          }
                          if (head) {
                            head.insertBefore(script,head.firstChild);
                          }
                     };
                 }
                 window.HASINJECTDRNAMICSCRIPT = true;
               };
    });
})();
(function () {
    if (window.BizLog) {
        return;
    }
    var BizLog = {
        _readyToRun: [],
        call: function () {
            var args = arguments;
            var argsList;
            try {
                argsList = [].slice.call(args, 0);
            } catch(ex) {
                var argsLen = args.length;
                argsList = [];
                for (var i=0; i<argsLen; i++) {
                    argsList.push(args[i]);
                }
            }

            BizLog.addToRun(function () {
                BizLog.call.apply(BizLog, argsList);
            });
        },
        addToRun: function (fn) {
            if (typeof fn==='function') {
                fn._logTimer = (new Date())-0;
                BizLog._readyToRun.push(fn);
            }
        }
    };

    window.BizLog = BizLog;
})();
(function(){
    function trimStr(str){
        if (str) {
            return str.replace(/^\s*|\s*$/,"");
        }
        return undefined;
    }
    var currentScale;
    var cssCaced = {};
    var componentIds = [];
    var componentsManager = {
          //NBComponent V2 begin
         createAnimationCls:function(css){
            if (typeof css == "string" &&  !cssCaced[css]) {
                var style = document.createElement('style');
                style.type = 'text/css';
                style.rel = 'stylesheet';
                style.appendChild(document.createTextNode(css));
                var head = document.head || document.documentElement;
                if (head) {
                  head.insertBefore(style, head.firstChild);
                }
                cssCaced[css] = "1";
            }
         },
         getScreenScale: function(){
                if (!currentScale) {
                    //compute scale
                    var viewPortTag = document.querySelector("meta[name=viewport]");
                    var viewPortContent;
                    if (viewPortTag) {
                        viewPortContent = viewPortTag.getAttribute("content");
                    };
                    var scaleValue = "0.33";
                    if (window.devicePixelRatio && window.devicePixelRatio > 2) {
                        scaleValue = "0.4235033";
                    };
                    if (viewPortContent) {
                        var contentList = viewPortContent.split(",");
                        for (var item in contentList) {
                            var scaleConfig = contentList[item].split("=");
                            if (scaleConfig && scaleConfig.length > 1) {
                                var scaleName = scaleConfig[0];
                                if (/initial-scale/.test(scaleName)) {
                                    scaleValue = scaleConfig[1];
                                    break;
                                };
                            };
                        }
                    };
                    currentScale = scaleValue;
                }
                return currentScale;
           },
          renderV2Internal: function (element, renderList, parentElementId) {
            var renderObj = {
                frame: {},
                data: {},
                props: {}
            };
            //compute id
            renderObj.id = trimStr(element.getAttribute("id"));

            //compute type
            renderObj.type = trimStr(element.getAttribute("nbcomponent-type"));

            //if is container
            // if (typeof renderObj.type == "string" && renderObj.type == "container") {
            //  return;
            // }

            //compute scale
            renderObj.scale = componentsManager.getScreenScale();

            //compute frame
            var boundRect = element.getBoundingClientRect();
            renderObj.frame.width = boundRect.width;
            renderObj.frame.height = boundRect.height;

            var scrollLeft = 0;
            if (document.documentElement && document.documentElement.scrollLeft) {
                scrollLeft = document.documentElement.scrollLeft;
            } else if (document.body) {
                scrollLeft = document.body.scrollLeft;
            }
            var x = boundRect.left + scrollLeft;
            renderObj.frame.x = x;

            var scrollTop = 0;
            if (document.documentElement && document.documentElement.scrollTop) {
                scrollTop = document.documentElement.scrollTop;
            } else if (document.body) {
                scrollTop = document.body.scrollTop;
            }
            var y = boundRect.top + scrollTop;
            renderObj.frame.y = y;

            //compute zindex
            if (element.style.zIndex === "") {
                renderObj.frame.zindex = "-9998";
            } else {
                renderObj.frame.zindex = element.style.zIndex;
            }
            if (element.style.zIndex === "" && element.parentElement.style.zIndex != "") {
                renderObj.frame.zindex = (parseInt(element.parentElement.style.zIndex) + 1).toString();
            }

            //compute custom-data
            var customData = trimStr(element.getAttribute("nbcomponent-data"));;
            if (customData) {
                try {
                    var customDic = JSON.parse(customData);
                    for (var key in customDic) {
                        renderObj.data[key] = customDic[key];
                    }
                } catch (ex) {

                }
            };

            if (parentElementId) {
                var style = window.getComputedStyle(element);
                if (style && style.fontFamily) {
                    renderObj.data["NBFONTFAMILY"] = style.fontFamily;
                }
                renderObj.data["NBPARENTELEMENTID"] =  parentElementId;
            }
            if (element.previousSibling && element.previousSibling.id) {
                renderObj.data["NBPREVIOUSSIBLINGID"] =  element.previousSibling.id;
            }
            //compute custom-data
             var customProps = trimStr(element.getAttribute("nbcomponent-props"));;
             if (customProps) {
                 try {
                    var customDic = JSON.parse(customProps);
                    for (var key in customDic) {
                        renderObj.props[key] = customDic[key];
                    }
                 } catch (ex) {

                 }
             };

            renderList.push(renderObj);
        },

        renderV2: function (id) {
            var renderList = [];
            var element = document.getElementById(id);
            if (element) {
                var parentNode = element.parentNode;
                var parentId = null;
                if (parentNode && parentNode.id) {
                    parentId = parentNode.id;
                }
                this.traverseTree(element, renderList, parentId);
            }
            return JSON.stringify(renderList);
        },

        hasClass: function(elem, className){
            var classes = elem.className.split(/\s+/) ;
            for(var i= 0 ; i < classes.length ; i ++) {
                if( classes[i] === className ) {
                    return true ;
                }
            }
            return false ;
        },
        addCls:function addClass(ele,cls) {
          if (!this.hasClass(ele,cls)) ele.className += " "+cls;
        },
        traverseTree: function (element, renderList, parentElementId) {
            if (this.hasClass(element, 'nbcomponent')) {
                this.renderV2Internal(element, renderList, parentElementId);
            }
            var nbcomponentType = element.getAttribute("nbcomponent-type");
            if (nbcomponentType && typeof nbcomponentType === "string") {
                nbcomponentType = trimStr(nbcomponentType);
            }
            //because image is atomaic component we should not get children
            if (!element.children || element.children.length <= 0 || (typeof nbcomponentType == "string" && (nbcomponentType == "image" || nbcomponentType == "text"))) {
                return;
            }
            for (var i = 0; i < element.children.length; i++) {
               this.traverseTree(element.children[i], renderList, element.id);
            }
        },
        //NBComponent V2 end
        getElementInfoById:function(id){
            var objectElements = Array.prototype.slice.call(document.querySelectorAll("object[type=application\\/view]"));
            var result = {};
            if (objectElements) {
                for(var element in objectElements){
                    var childNodes = Array.prototype.slice.call(objectElements[element].childNodes);
                    if (childNodes) {
                        for(var index in childNodes){
                            var childNode = childNodes[index];
                            var childNodeTag = childNode.tagName;
                            if (childNodeTag && /param/i.test(childNodeTag)) {
                                var name = trimStr(childNode.getAttribute("name"));
                                var value = trimStr(childNode.getAttribute("value"));
                                if(name && value){
                                    result[name] = value;
                                }
                            }
                        }
                    };
                    if (result.id && result.id == id) {
                        result["element"] = objectElements[element];
                        break;
                    };
                }
            };
            return result;
        },
        createTargetAnimationWithId:function(id){
            var clsMode = ".nbcomponentanimation-%@{-webkit-animation:nbcomponentopacity%@ 100s infinite linear}@-webkit-keyframes nbcomponentopacity%@{0%{-webkit-transform:translateZ(0)}100%{-webkit-transform:translateZ(0)}}";
            return clsMode.replace(/%@/g,id);
        },
        addListenerForDomChange:function(){
            var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
            var target = document.querySelector('body');
            var observer = new MutationObserver(function(mutations) {
                for(var i=0 ;i<componentIds.length; i++){
                    var item = componentIds[i];
                    if (typeof item === "string" && window.AlipayJSBridge) {
                        AlipayJSBridge.call("NBComponent.setData",{
                            element:item,
                            NEBULAFRAMEDATA:JSON.parse(componentsManager.render(item))
                        },function(){});
                    }
                }
            });
            var config = { attributes: true, childList: true, subtree: true, attributeFilter:["class","style"]}
            observer.observe(target, config);
        },
        render:function(id){
            var elementInfo = this.getElementInfoById(id);
            if(elementInfo && elementInfo.element){
                componentsManager.createAnimationCls(componentsManager.createTargetAnimationWithId(id));
                var element = elementInfo.element;
                componentsManager.addCls(element,'nbcomponentanimation'+"-"+id);
                var type = elementInfo["type"];
                //if is nbcomponent
                var scaleValue = componentsManager.getScreenScale();
                
                var renderObj = {
                                    id:id,
                                    scale:scaleValue,
                                    type:type,
                                    frame:{},
                                    data:{}
                };
                
                renderObj.clsName = element.className;

                var boundRect = element.getBoundingClientRect();
                renderObj.frame.width = boundRect.width;
                renderObj.frame.height = boundRect.height;
                
                var scrollLeft = 0;
                if (document.documentElement && document.documentElement.scrollLeft){
                    scrollLeft = document.documentElement.scrollLeft;
                }else if (document.body){
                    scrollLeft = document.body.scrollLeft;
                }
                var x = element.getBoundingClientRect().left + scrollLeft;
                renderObj.frame.x = x;

                var scrollTop = 0;
                if (document.documentElement && document.documentElement.scrollTop){
                    scrollTop = document.documentElement.scrollTop;
                }else if (document.body){
                    scrollTop = document.body.scrollTop;
                }
                var y = element.getBoundingClientRect().top + scrollTop;
                renderObj.frame.y = y;

                //get custom-data
                var customData = elementInfo["data"];
                if (customData) {
                    try{
                        var customDic = JSON.parse(customData);
                        for (var key in customDic){
                            renderObj.data[key] = customDic[key];
                        }
                    }catch(ex){

                    }
                };
                // merge other config to render data obj
                try{
                    for(var key in elementInfo){
                        if (!/^(?:data|id|type|element)$/.test(key)) {
                            renderObj.data[key] = elementInfo[key];
                        };
                    }
                }catch(ex){
                }
                if (componentIds && componentIds.indexOf((id+"")) == -1) {
                    componentIds.push((id+""));
                }
                //return config
                return JSON.stringify(renderObj);
            }
        }
    };
    function onDOMReady(callback) {
        var readyRE = /complete|loaded|interactive/;
        if (readyRE.test(document.readyState)) {
            setTimeout(function() {
                       callback();
                       }, 1);
        } else {
            document.defaultView.addEventListener('DOMContentLoaded', function () {
                callback();
            }, false);
        }
    }
    onDOMReady(function(){
        componentsManager.addListenerForDomChange();
    });
    window.componentsManager = componentsManager;
})();
window.ALIPAYH5STARTUPPARAMS.passData=。。。。。。。

 

把这段报文 注入到webview  ,完成。

NSString *path = [[NSBundle mainBundle]pathForResource:@"truePassData.js" ofType:nil];
NSString *filename = [[NSString alloc]initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
WKUserScript *script = [[WKUserScript alloc] initWithSource:filename injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
[self addUserScriptS:script];

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值