欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-27 19:13:38
...

 

 

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

手机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过来吧

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

//
//  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请求没有走到这里。看来只能使用上面的方法解决。

 

 

重复上面的话:B功能的离线包正常打开,A功能的h5离线包白屏。 

是不是想起来和客户端一点关系没有。

 

????????????????????????????????????????????????????????????????????????????????????????????????????????????????

 

学h5转h5去了。。。。。

 

 

客户端能做的也就这些了吧

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关标签: mpaas离线包