如何在本地webview打開 遠程h5頁面;javascript
有的時候,想要在app上直接調試樣式,功能等,可是每次修改後都要從新部署,非常麻煩,所以,參考各方文檔後,瞭解到我的認爲最優的解決方案,方案以下:html
默認狀況下打開遠程h5頁面會調用本地瀏覽器打開;因此咱們須要在cofig.xml添加代碼;java
<allow-navigation href="http://*/*" /> <allow-navigation href="https://*/*" /> <content src="url">//這個是啓動是打開的頁面
第一步就完成了。android
h5頁面調用本地插件接口web
方法一:首先本地先安裝好插件,而後就是簡單粗暴將cordova.js plugin等全部js文件一塊兒放在服務器上。h5頁面只須要引用cordova.js便可(所需文件在platforms/andriod/assets/www/)亦或(platforms/andriod/platform_www);這種方法缺點不少,好比下載的流量會增長,沒法經過appstore審覈;apache
方法二:上面的js文件是放在服務器上的,那麼咱們是否是能夠直接讓h5使用本地cordova.js等文件,這樣就不存在從新下那麼多js文件的問題了。瀏覽器
<script src="file:///android_asset/www/cordova.js" type="text/javascript" charset="UTF-8"></script>
不過遇到了一個錯誤:
Not allowed to load local resource: file:///android_asset/www/cordova.js
意思是http協議下禁止經過file://方式訪問本地的文件。安全
不過若是cordova app就是訪問的file://android_asset/www/index.html的話,加載其它file://資源是沒問題的。服務器
這是webview的一種安全機制。app
解決辦法是,經過攔截webview的請求,實現加載本地js,具體以下:
打開platforms/andriod/CordovaLib/src/org/apache/cordova/engine/SystemWebViewClient.java
public void clearAuthenticationTokens() { this.authenticationTokens.clear(); } private static final String INJECTION_TOKEN = "http://injection/"; //新增 @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { ---新增--- if(url != null && url.contains(INJECTION_TOKEN)) { String assetPath = url.substring(url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length(), url.length()); try { WebResourceResponse response = new WebResourceResponse( "application/javascript", "UTF8", view.getContext().getAssets().open(assetPath) ); return response; } catch (IOException e) { e.printStackTrace(); // Failed to load asset file return new WebResourceResponse("text/plain", "UTF-8", null); } } ---新增--- try { // Check the against the whitelist and lock out access to the WebView directory // Changing this will cause problems for your application if (!parentEngine.pluginManager.shouldAllowRequest(url)) { LOG.w(TAG, "URL blocked by whitelist: " + url); // Results in a 404. return new WebResourceResponse("text/plain", "UTF-8", null); } CordovaResourceApi resourceApi = parentEngine.resourceApi; Uri origUri = Uri.parse(url); // Allow plugins to intercept WebView requests. Uri remappedUri = resourceApi.remapUri(origUri); if (!origUri.equals(remappedUri) || needsSpecialsInAssetUrlFix(origUri) || needsKitKatContentUrlFix(origUri)) { CordovaResourceApi.OpenForReadResult result = resourceApi.openForRead(remappedUri, true); return new WebResourceResponse(result.mimeType, "UTF-8", result.inputStream); } // If we don't need to special-case the request, let the browser load it. return null; } catch (IOException e) { if (!(e instanceof FileNotFoundException)) { LOG.e(TAG, "Error occurred while loading a file (returning a 404).", e); } // Results in a 404. return new WebResourceResponse("text/plain", "UTF-8", null); } }
注意:若是你用了cordova-plugin-crosswalk-webview插件,則須要打開cordova-plugin-crosswalk-webviewplatformsandroidsrcorgcrosswalkengineXWalkCordovaResourceClient.java
修改shouldInterceptLoadRequest方法。
最後咱們把外鏈的h5頁面中cordova.js路徑改爲下面的;
<script src="http://injection/www/cordova.js" type="text/javascript" charset="UTF-8"></script>
思路是:既然不容許訪問"file://,那我就設法改成http://,而後攔截webview的請求,對http://injection/開頭的請求,手動返回對應文件的具體內容。
最後從新打包就能夠了。。。