猜想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];
、