mPaas离线包之内网环境iOS客户端白页问题查看从入门到放弃

手机连不上内网已经解决了,

手机udid没加也解决了。

不得不说mPaas把h5容器封装的很死,即使完全知道本地h5如何在webview加载的,也很难查看其问题。

h5离线包只能加载从发布平台导出来的h5代码,即使想改,自己也改不了,改了,也得在发布平台重新发布才可以用。

如果是明文的h5自己就可以拦截替换一些文件,随便加点代码。

解决:修改h5代码(加点弹窗),发布h5代码,可能需要很多次,查看哪行代码没有执行下去。在蚂蚁的人不改客户端的情形下。

混淆后的一个js文件有300k,900k,xcode打开都直接卡死。

下面是客户端能看到的 混淆后的js小部分
2,0),a.maxY=-a.minY,a.touchesCurrent.x="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,a.touchesCurrent.y="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,!a.isMoved&&!i.isScaling){if(t.isHorizontal()&&(Math.floor(a.minX)===Math.floor(a.startX)&&a.touchesCurrent.x<a.touchesStart.x||Math.floor(a.maxX)===Math.floor(a.startX)&&a.touchesCurrent.x>a.touchesStart.x))return void(a.isTouched=!1);if(!t.isHorizontal()&&(Math.floor(a.minY)===Math.floor(a.startY)&&a.touchesCurrent.y<a.touchesStart.y||Math.floor(a.maxY)===Math.floor(a.startY)&&a.touchesCurrent.y>a.touchesStart.y))return void(a.isTouched=!1)}e.preventDefault(),e.stopPropagation(),a.isMoved=!0,a.currentX=a.touchesCurrent.x-a.touchesStart.x+a.startX,a.currentY=a.touchesCurrent.y-a.touchesStart.y+a.startY,a.currentX<a.minX&&(a.currentX=a.minX+1-Math.pow(a.minX-a.currentX+1,.8)),a.currentX>a.maxX&&(a.currentX=a.maxX-1+Math.pow(a.currentX-a.maxX+1,.8)),a.currentY<a.minY&&(a.currentY=a.minY+1-Math.pow(a.minY-a.currentY+1,.8)),a.currentY>a.maxY&&(a.currentY=a.maxY-1+Math.pow(a.currentY-a.maxY+1,.8)),n.prevPositionX||(n.prevPositionX=a.touchesCurrent.x),n.prevPositionY||(n.prevPositionY=a.touchesCurrent.y),n.prevTime||(n.prevTime=Date.now()),n.x=(a.touchesCurrent.x-n.prevPositionX)/(Date.now()-n.prevTime)/2,n.y=(a.touchesCurrent.y-n.prevPositionY)/(Date.now()-n.prevTime)/2,Math.abs(a.touchesCurrent.x-n.prevPositionX)<2&&(n.x=0),Math.abs(a.touchesCurrent.y-n.prevPositionY)<2&&(n.y=0),n.prevPositionX=a.touchesCurrent.x,n.prevPositionY=a.touchesCurrent.y,n.prevTime=Date.now(),s.$imageWrapEl.transform("translate3d("+a.currentX+"px, "+a.currentY+"px,0)")}}},onTouchEnd:function(){var e=this.zoom,t=e.gesture,i=e.image,s=e.velocity;if(t.$imageEl&&0!==t.$imageEl.length){if(!i.isTouched||!i.isMoved)return i.isTouched=!1,void(i.isMoved=!1);i.isTouched=!1,i.isMoved=!1;var a=300,n=300,r=s.x*a,o=i.currentX+r,l=s.y*n,d=i.currentY+l;0!==s.x&&(a=Math.abs((o-i.currentX)/s.x)),0!==s.y&&(n=Math.abs((d-i.currentY)/s.y));var c=Math.max(a,n);i.currentX=o,i.currentY=d;var p=i.width*e.scale,h=i.height*e.scale;i.minX=Math.min(t.slideWidth/2-p/2,0),i.maxX=-i.minX,i.minY=Math.min(t.slideHeight/2-h/2,0),i.maxY=-i.minY,i.currentX=Math.max(Math.min(i.currentX,i.maxX),i.minX),i.currentY=Math.max(Math.min(i.currentY,i.maxY),i.minY),t.$imageWrapEl.transition(c).transform("translate3d("+i.currentX+"px, "+i.currentY+"px,0)")}},onTransitionEnd:function(){var e=this.zoom,t=e.gesture;t.$slideEl&&this.previousIndex!==this.activeIndex&&(t.$imageEl.transform("translate3d(0,0,0) scale(1)"),t.$imageWrapEl.transform("translate3d(0,0,0)"),e.scale=1,e.currentScale=1,t.$slideEl=void 0,t.$imageEl=void 0,t.$imageWrapEl=void 0)},toggle:function(e){var t=this.zoom;t.scale&&1!==t.scale?t.out():t.in(e)},in:function(t){var i,s,a,n,r,o,l,d,c,p,h,u,v,m,f,g,y=this,w=y.zoom,b=y.params.zoom,C=w.gesture,S=w.image;C.$slideEl||(C.$slideEl=y.clickedSlide?e(y.clickedSlide):y.slides.eq(y.activeIndex),C.$imageEl=C.$slideEl.find("img, svg, canvas"),C.$imageWrapEl=C.$imageEl.parent("."+b.containerClass)),C.$imageEl&&0!==C.$imageEl.length&&(C.$slideEl.addClass(""+b.zoomedSlideClass),void 0===S.touchesStart.x&&t?(i="touchend"===t.type?t.changedTouches[0].pageX:t.pageX,s="touchend"===t.type?t.changedTouches[0].pageY:t.pageY):(i=S.touchesStart.x,s=S.touchesStart.y),w.scale=C.$imageWrapEl.attr("data-swiper-zoom")||b.maxRatio,w.currentScale=C.$imageWrapEl.attr("data-swiper-zoom")||b.maxRatio,t?(f=C.$slideEl[0].offsetWidth,g=C.$slideEl[0].offsetHeight,a=C.$slideEl.offset().le

客户端调用方法有限。

通过控制台的打印:在加载h5包时会有一些日志打印发现了两点

1.行为分析的外网js,通过MyConnectionURLProtocol拦截到外网的js链接地址,然后从整个工程扫描这个地址,发现是行为分析的framework里面的。

把他关掉:NBLogConfigurationGet().shouldInjectSPMJS = NO;


2.长链接:通过c语言hook系统日志打印方法nslog发现有几个日志是[DTLongLinkDataDispatch cmdTimeout:]打印出来的。

然后把他也关掉    [MySyncService sharedInstance]这个方法注释掉。

再然后控制台没有什么有用信息了。

开始的时候又写了一个MyConnectionURLProtocol。想拦截处理,但是蚂蚁内部已经有了一个PSDWebViewURLProtocol,这样两个都会走。那就把PSDWebViewURLProtocol的方法都hook过来吧

//
//  PSDWebViewURLProtocol+YYY.h
//  
//
//  Created by YYY on 2019/9/10.
//  Copyright © 2019 Alibaba. All rights reserved.
//



NS_ASSUME_NONNULL_BEGIN
@interface PSDWebViewURLProtocol:NSURLProtocol
@end

@interface PSDWebViewURLProtocol (YYY)

@end

NS_ASSUME_NONNULL_END
//
//  PSDWebViewURLProtocol+YYY.m
//
//
//  Created by YYY on 2019/9/10.
//  Copyright © 2019 Alibaba. All rights reserved.
//

#import "PSDWebViewURLProtocol+YYY.h"

@interface PSDWebViewURLProtocol () <NSURLConnectionDataDelegate>

@property (nonatomic, strong) NSURLConnection * connection;
@property (nonatomic, assign) NSStringEncoding stringEncoding ;
@end

@implementation PSDWebViewURLProtocol (YYY)
+ (void)load
{
    {
        Method originalMethod = class_getClassMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(canInitWithRequest:));
        
        Method swizzledMethod = class_getClassMethod([self class], @selector(canInitWithRequestS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    {
        Method originalMethod = class_getClassMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(canonicalRequestForRequest:));
        
        Method swizzledMethod = class_getClassMethod([self class], @selector(canonicalRequestForRequestS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    {
        Method originalMethod = class_getInstanceMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(startLoading));
        
        Method swizzledMethod = class_getInstanceMethod([self class], @selector(stopLoadingS));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    {
        Method originalMethod = class_getInstanceMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(connection:didReceiveResponse:));
        
        Method swizzledMethod = class_getInstanceMethod([self class], @selector(connection:didReceiveResponseS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    {
        Method originalMethod = class_getInstanceMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(connection:didReceiveData:));
        
        Method swizzledMethod = class_getInstanceMethod([self class], @selector(connection:didReceiveDataS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    {
        Method originalMethod = class_getInstanceMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(connectionDidFinishLoading:));
        
        Method swizzledMethod = class_getInstanceMethod([self class], @selector(connectionDidFinishLoadingS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    {
        Method originalMethod = class_getInstanceMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(connection:didFailWithError:));
        
        Method swizzledMethod = class_getInstanceMethod([self class], @selector(connection:didFailWithErrorS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    //
    //
    //
    //
}

+ (BOOL)canInitWithRequestS:(NSMutableURLRequest *)request {
    
    NSMutableURLRequest *mutableReq = [request mutableCopy];
    NSMutableDictionary *headers = [mutableReq.allHTTPHeaderFields mutableCopy];
    if ([headers[@"Key1"]  isEqualToString:@"AAAA" ]){
        return NO;
    }  
    
    if([request .URL.description hasPrefix:@"http://"]){
//        return YES;
    }
    
    NSLog(@"PSDWebViewURLProtocol canInitWithRequestS %@" ,request);;
    return [self canInitWithRequestS:request];
}
//
//修改请求头 防止死循环
//
+ (NSURLRequest *)canonicalRequestForRequestS:(NSURLRequest *)request {
    
    if([request .URL.description hasPrefix:@"http://"]){
        // 修改了请求的头部信息
        NSMutableURLRequest *mutableRequest = [request mutableCopy];
        [mutableRequest setValue:@"AAAA" forHTTPHeaderField:@"Key1"];
        
        if ([mutableRequest allHTTPHeaderFields].count < 1) {
            NSLog(@"空的空的");
        }
        NSLog(@"connection reset header");
        return mutableRequest;
        return request;
    }else{
        return [self canonicalRequestForRequestS:request];

    }
    

}

//
//开始加载
//
- (void)startLoadingS{
    
    
    NSMutableURLRequest *request = [self.request mutableCopy];

    if([request .URL.description hasPrefix:@"http://"]){

        self.connection = [NSURLConnection connectionWithRequest:request delegate:self];

    }else{
         [self startLoadingS];

    }
    
//替换为本地文件使用下面方法
//    if ([request.URL.absoluteString containsString:@"hhhh"]) {
//        NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[[self request] URL]
//                                                              statusCode:200
//                                                             HTTPVersion:@"1.1"
//                                                            headerFields:nil];
//        //
//        //如果是需要更改的页面则直接把数据返回给它 这个文件里的代码是通过第一次打印复制出来更改后的
//        //
//        NSString *myStr = [[NSBundle mainBundle]pathForResource:@"20190730_0.0.0.2" ofType:@"amr" inDirectory:nil];
//        NSData *localdata = [[NSData alloc]initWithContentsOfFile:myStr];
//        [[self client] URLProtocol:self
//                didReceiveResponse:response
//                cacheStoragePolicy:NSURLCacheStorageNotAllowed];
//        [[self client] URLProtocol:self didLoadData:localdata];
//        [[self client] URLProtocolDidFinishLoading:self];
//    }

}

//
//取消请求
//
- (void)stopLoadingS {
    
     [self stopLoadingS];
    
    
//    [self.connection cancel];
}

//
//#pragma mark - NSURLConnectionDelegate
//
- (void)connection:(NSURLConnection *)connection didReceiveResponseS:(NSURLResponse *)response {
    NSMutableURLRequest *request = [self.request mutableCopy];
    
    if([request .URL.description hasPrefix:@"http://"]){
        
        [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];

    }
      [self connection:connection didReceiveResponseS:response];
    
}
- (void)connection:(NSURLConnection *)connection didReceiveDataS:(NSData *)data {
    
    NSMutableURLRequest *request = [self.request mutableCopy];

    if([request .URL.description hasPrefix:@"http://"]){
        NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];;
        if (str.length < 1) {
            CFStringEncoding gbkEncoding =(unsigned int) CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
            
            str =[[NSString alloc]initWithData:data encoding:gbkEncoding];
        }
        //
        //打印h5的代码
        //
        NSLog(@"%@ %@",connection,str);
        [self.client URLProtocol:self didLoadData:data];
        
    }else{
        return [self connection:connection didReceiveDataS:data];

    }
    

    

}
- (void)connectionDidFinishLoadingS:(NSURLConnection *)connection {
    NSMutableURLRequest *request = [self.request mutableCopy];
    
    if([request .URL.description hasPrefix:@"http://"]){
        [self.client URLProtocolDidFinishLoading:self];
    }else{
        [self connectionDidFinishLoadingS:connection];

    }
    
//
}
- (void)connection:(NSURLConnection *)connection didFailWithErrorS:(NSError *)error {
    
    NSMutableURLRequest *request = [self.request mutableCopy];
    
    if([request .URL.description hasPrefix:@"http://"]){
            [self.client URLProtocol:self didFailWithError:error];

    }else{
    [self connection:connection didFailWithErrorS:error];
    }
}

@end

这些代码添加后能够走进来,对A功能的h5离线包也能正常打开。

但是对于一直白屏的B功能,还是白屏,而且要找的那个http请求没有走到这里。看来只能使用上面的方法解决。

发布了120 篇原创文章 · 获赞 15 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_15509071/article/details/102695068