【问题标题】:Intercept responses from WebSocket connection in UIWebView在 UIWebView 中拦截来自 WebSocket 连接的响应
【发布时间】:2018-01-27 20:59:28
【问题描述】:
我有一个应用程序,里面有一个 UIWebView 和一个加载的网站。该网站中有一个图表,该图表通过 websockets (socket.io) 使用来自远程服务器的数据定期更新。
我是 websockets 技术的新手,但我试图以某种方式拦截网站通过它从服务器接收的图表数据。
到目前为止,我已经成功捕获了这种地址格式的网站发送的http请求:“http://website-address/socket.io/?auth_token=...”
我有 iOS 的 socket.io 库,但不知道如何使用它来欺骗网站连接并获取网站下载的数据。任何人都可以帮忙吗?有没有可能?
【问题讨论】:
标签:
ios
objective-c
websocket
socket.io
intercept
【解决方案1】:
如果可以,请切换到 WKWebView。在那里使用 javascript 桥接器要容易得多。也就是说,使用UIWebView,您需要注入一个脚本,该脚本为您尝试侦听的套接字接收的事件添加处理程序。您可以自己创建一个io 变量,但显然服务器需要身份验证令牌。如果您无法创建身份验证令牌,则只有在您有权访问网站创建的 io 变量时才能执行此操作。
然后,要添加处理程序,您需要知道传递图表数据的事件名称是什么。您可以窥探该网站,看看是否可以找到。如果你不能所有的赌注都关闭。一旦我们注册了一个处理程序并获取了数据,我们需要将它传递回您的本机代码。这就是WKWebView 通过让您添加可以将消息从 js 传递到本机代码的消息处理程序来保持干净的地方。对于UIWebView,您必须创建自定义 url 方案并欺骗导航请求以传递数据。让我们假设您的自定义 url 方案是“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;
}
【解决方案2】:
关于 Santhosh R 的回答。我遇到了他提到的问题,我无法获得对 websocket 对象的引用,因为它陷入了闭包中。
我通过添加一个预加载脚本解决了这个问题,该脚本包装了本机 Websocket 对象以将任何实例化的 Websocket 对象存储在一个数组中,然后返回新创建的 Websocket 对象。
这是代码。
在您的 WebView 元素中添加预加载属性。
<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 对象的数组