簡體   English   中英

Android Web-View:將本地Javascript文件注入遠程網頁

[英]Android Web-View : Inject local Javascript file to Remote Webpage

之前已經多次詢問過,我瀏覽了所有內容,還沒有明確的答案。

問題簡化:是否可以將本地Javascript文件(從資產或存儲)注入Android Web視圖中加載的遠程網頁? 我知道可以將這些文件注入Web-View中加載的本地Web頁面(Assets HTML)。

為什么我需要這個呢? :通過避免每次都下載較大的文件(如Js和CSS文件)來提高瀏覽體驗。 我想避免Web-View緩存。

有一種方法可以“強制”從本地資產(例如,assets / js / script.js)注入本地Javascript文件,並繞過'不允許加載本地資源:file:/// android_assets / js /script.js ...'問題。

它類似於另一個線程( Android webview,在assets文件夾中加載javascript文件 )中描述的內容,以及用於將Javascript文件表示為可打印字符串的附加BASE64編碼/解碼。

我使用的是Android 4.4.2,API級別19虛擬設備。

以下是一些代碼段:

[資產/ JS /的script.js]:

    'use strict';

    function test() {
       // ... do something
    }

    // more Javascript

[MainActivity.java]:

    ...

    WebView myWebView = (WebView) findViewById(R.id.webView);
    WebSettings webSettings = myWebView.getSettings();

    webSettings.setJavaScriptEnabled(true);
    webSettings.setAllowUniversalAccessFromFileURLs(true);
    myWebView.setWebViewClient(new WebViewClient() {
       @Override
       public boolean shouldOverrideUrlLoading(WebView view, String url) {
          return false;
       }

       @Override
       public void onPageFinished(WebView view, String url) {
          super.onPageFinished(view, url);

          injectScriptFile(view, "js/script.js"); // see below ...

          // test if the script was loaded
          view.loadUrl("javascript:setTimeout(test(), 500)");
       }

       private void injectScriptFile(WebView view, String scriptFile) {
          InputStream input;
          try {
             input = getAssets().open(scriptFile);
             byte[] buffer = new byte[input.available()];
             input.read(buffer);
             input.close();

             // String-ify the script byte-array using BASE64 encoding !!!
             String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
             view.loadUrl("javascript:(function() {" +
                          "var parent = document.getElementsByTagName('head').item(0);" +
                          "var script = document.createElement('script');" +
                          "script.type = 'text/javascript';" +
             // Tell the browser to BASE64-decode the string into your script !!!
                          "script.innerHTML = window.atob('" + encoded + "');" +
                          "parent.appendChild(script)" +
                          "})()");
          } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
          }
       }
    });

    myWebView.loadUrl("http://www.example.com");

    ...

是的,您可以使用shouldInterceptRequest()來攔截遠程URL加載並返回本地存儲的內容。

WebView webview = (WebView) findViewById(R.id.webview);

webview.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
       if (url.equals("script_url_to_load_local")) {
           return new WebResourceResponse("text/javascript", "UTF-8", new FileInputStream("local_url")));
       } else {
           return super.shouldInterceptRequest(view, url);
       }
    }
});

loadUrl僅適用於舊版本使用evaluateJavascript

webview.evaluateJavascript("(function() { document.getElementsByName('username')[0].value='USERNAME';document.getElementsByName('password')[0].value='PASSWORD'; "+
"return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String s) {
                    Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"}
                }
            });

小心使用evaluateJavascript :如果你的javascript中拋出了語法錯誤或異常,它將使用null調用你的onReceiveValue 支持SDK 19和更低版本的最常見方式似乎是這樣: 使用Javascript在WebView中填寫表單

此外,如果您非常渴望某種瀏覽器功能(在我的情況下,永遠無法弄清楚如何讓DRM正常工作)您可以在普通的chrome中使用書簽,只有當您在多功能框中鍵入書簽名稱時才有效但確實工作,並注入javascript。

另請注意,使用默認WebView您無法使用javascript警報來測試任何內容,但它們不會顯示。 另請注意,默認情況下“視頻”(如html <video>標簽)默認情況下“無法正常工作”,默認情況下DRM視頻也不起作用,它們都是配置選項:\\

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM