Android Web-View: wstrzyknij lokalny plik Javascript do zdalnej strony internetowej

To było pytane wiele razy wcześniej, przeglądałem wszystko, nie ma jeszcze jasnych odpowiedzi.

Pytanie uproszczone: czy możliwe jest wstrzyknięcie lokalnego pliku Javascript (z zasobu lub pamięci masowej) do zdalnej strony internetowej załadowanej w widoku sieci Android? Wiem, że możliwe jest wstrzyknięcie takich plików do lokalnych stron internetowych (Assets HTML) załadowanych w widoku sieci Web.

Po co mi to? : Aby przyspieszyć przeglądanie, unikając pobierania większych plików, takich jak Pliki JS i CSS za każdym razem. Chcę uniknąć buforowania widoku sieci.

Author: sumit, 2014-02-04

4 answers

Istnieje sposób, aby "wymusić" wstrzyknięcie lokalnych plików Javascript z zasobów lokalnych (np. assets/js/script.js), i obejść ' nie wolno załadować lokalnego zasobu: file: / / / android_assets / js / script.js ...'problem.

Jest to podobne do tego, co opisano w innym wątku (Android webview, ładowanie pliku javascript w folderze assets), z dodatkowym kodowaniem/dekodowaniem BASE64 do reprezentowania pliku Javascript jako drukowalnego ciągu.

Używam Android 4.4.2, API poziom 19 urządzenie wirtualne.

Oto kilka fragmentów kodu:

[assets / js / script.js]: {]}

    'use strict';

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

    // more Javascript

[główna aktywność.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");

    ...
 46
Author: Raffaele N.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:24

Tak, możesz użyć shouldInterceptRequest() do przechwycenia Zdalnego Ładowania url i zwrócenia lokalnej przechowywanej zawartości.

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);
       }
    }
});
 5
Author: cyberflohr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 18:31:01

LoadUrl będzie działał tylko w starej wersji use 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"}
                }
            });
 5
Author: rinkesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-01 20:15:40

Bądź ostrożny używając evaluateJavascript: jeśli wystąpi błąd składni lub wyjątek w Twoim javascript, wywoła on onReceiveValue Z null. Najczęstszym sposobem obsługi zarówno SDK 19, jak i lower wydaje się być tak: wypełnij formularz w WebView za pomocą Javascript

Również jeśli masz strasznie zdesperowany do jakiegoś rodzaju funkcjonalności przeglądarki (w moim przypadku, nigdy nie mógł dowiedzieć się, jak sprawić, aby DRM działał dobrze) można użyć bookmarklet w normalnym chrome, który działa tylko wtedy, gdy wpiszesz nazwa zakładki do omnibox, ale działa i wstrzykuje javascript.

Należy również pamiętać, że z domyślnym WebView nie można używać alertów javascript do testowania czegokolwiek, nie pokazują. Należy również pamiętać, że" wideo "domyślnie (jak znaczniki html ) nie" naprawdę działa " domyślnie, a także wideo DRM nie działa domyślnie, wszystkie są opcje konfiguracji: \

 0
Author: rogerdpack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 04:21:04