cordova 遠程h5頁面調用本地js

如何在本地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/開頭的請求,手動返回對應文件的具體內容。

最後從新打包就能夠了。。。

clipboard.png

相關文章
相關標籤/搜索