在UIWebView中拦截来自WebSocket连接的响应

时间:2018-01-27 20:59:28

标签: ios objective-c websocket socket.io intercept

我有一个应用程序,里面有一个带有加载网站的UIWebView。该网站上有一个图表,它通过websockets(socket.io)定期更新来自远程服务器的数据。

我是websockets技术的新手,但我试图以某种方式拦截网站通过它从服务器接收的图表数据。

直到现在我已设法捕获网站发送的这种地址格式的http请求:“http://website-address/socket.io/?auth_token= ...” 我有适用于iOS的socket.io库,但不知道如何使用它以某种方式欺骗网站连接并获取网站下载的数据。有人可以帮忙吗?它甚至可能吗?

2 个答案:

答案 0 :(得分:1)

如果可以,请切换到WKWebView。使用javascript桥更容易。也就是说,使用UIWebView,您需要注入一个脚本,为您尝试侦听的套接字接收的事件添加处理程序。您可以自己创建io变量,但显然服务器需要auth令牌。如果您无法创建身份验证令牌,则只有在您可以访问网站创建的io变量时才能执行此操作。
然后,为了添加处理程序,您需要知道事件名称是什么,它提供图表数据。你可以窥探网站,看看你是否能找到它。如果你不能全部下注。一旦我们注册了一个处理程序并获取数据,我们需要将其传递回您的本机代码。这是WKWebView通过允许您添加可以将消息从js传递到本机代码的消息处理程序来保持其清洁的地方。对于UIWebView,您必须创建自定义网址方案并欺骗导航请求以传递数据。假设您的自定义网址方案是“myApp”。然后你需要注入的脚本是:

<script>
  /* if you can access/create the auth token
   var socket = io('http://website-address/socket.io/?auth_token=');
  */
   var socket = getioReferenceCreatedByWebsite();
   socket.on('<eventName>',function(){
       window.location = 'myApp://<data>';
   };
</script>

在您的原生代码中:

...
webView.delegate = self;
[webView stringByEvaluatingJavaScriptFromString:@"<theAboveJSAsAString>"];
....
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
   if(request.URL.scheme == @"myApp"){
      NSString *data = request.URL.path;
      //handle the data
      return NO;
   } 
   return YES;
}

答案 1 :(得分:0)

关于Santhosh R的回答。我遇到了他提到的问题,在该问题中我无法获得对websocket对象的引用,因为该对象被封闭了。

我通过添加一个预加载脚本解决了这个问题,该脚本包装了本地Websocket对象,以将任何实例化的websocket对象存储在数组中,然后返回新创建的websocket对象。

这是代码。

在WebView元素中的

中添加一个preload属性。

<webview id="myWebview" src="http://exmple.com" preload="./interceptor.js"></webview>

然后进入inteceptor.js

window.NativeWebsocket = WebSocket;
window.WebSocket = function(url, protocols){
    window.interceptedWebsockets = [];
    var ws = new NativeWebsocket(url, protocols);
    interceptedWebsockets.push(ws);
    return ws;
}

然后,在WebView上下文中,您可以使用window.interceptedWebsockets

访问实例化的websocket对象的访问数组。