我们希望使用原始的Android WebView作为一个沙盒来执行本地HTML/JS应用程序。一个主要的安全需求是将WebView完全设置为离线,并且只允许调用一些特定的javascript接口。这些接口是使用WebView.addJavascriptInterface()方法传递到javascript运行时中的。
Android应用程序本身具有访问网络的权限(android.permission.INTERNET)。
我能够禁用普通的http/https请求,但是在阻止WebSocket请求方面彻底失败了。似乎这些请求与普通的http请求不同。
一种替代方法是覆盖WebSocket JavaScript方法。但这让我感觉很糟糕,因为它违反了沙盒概念。也似乎可以使用delete来恢复原始函数指针。
另一种选择是将自定义的WebView(例如Crosswalk-Project)与我们的应用程序捆绑在一起,但是我们想避免这样做,因为编译和更新需要相当大的工作量。
我尝试了以下公共WebView接口,但似乎没有一个能够阻止WebSocket调用:
Android应用程序本身具有访问网络的权限(android.permission.INTERNET)。
我能够禁用普通的http/https请求,但是在阻止WebSocket请求方面彻底失败了。似乎这些请求与普通的http请求不同。
一种替代方法是覆盖WebSocket JavaScript方法。但这让我感觉很糟糕,因为它违反了沙盒概念。也似乎可以使用delete来恢复原始函数指针。
另一种选择是将自定义的WebView(例如Crosswalk-Project)与我们的应用程序捆绑在一起,但是我们想避免这样做,因为编译和更新需要相当大的工作量。
我尝试了以下公共WebView接口,但似乎没有一个能够阻止WebSocket调用:
- webSettings.setBlockNetworkLoads(true);
- webSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
- webView.setNetworkAvailable(false);
- WebViewClient.shouldOverrideUrlLoading() (回调函数)
- WebViewClient.shouldInterceptRequest() (回调函数,尝试了两个版本)
- WebChromeClient.onPermissionRequest()
在Android 4.4.4(19)和Android 5 / 5.1(21/22)上测试通过。
我正在执行的javascript:
ws = new WebSocket("wss://echo.websocket.org");
ws.onmessage = function(event) {
console.log("received: " + event.data);
};
ws.onclose = function() {
console.log("External Socket closed");
};
ws.onopen = function() {
console.log("Connected to external ws");
ws.send("Hello from " + navigator.userAgent);
};
有任何想法如何完成这个任务吗?
非常感谢。