Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Web视图:将本地Javascript文件注入远程网页_Javascript_Android_Caching_Webview - Fatal编程技术网

Android Web视图:将本地Javascript文件注入远程网页

Android Web视图:将本地Javascript文件注入远程网页,javascript,android,caching,webview,Javascript,Android,Caching,Webview,以前有人问过很多次,我浏览了所有的东西,还没有明确的答案 简化问题:是否可以将本地Javascript文件(从资产或存储)注入到Android Web视图中加载的远程网页?我知道可以将这些文件注入到Web视图中加载的本地网页(HTML资产) 为什么我需要这个来工作通过避免每次下载更大的文件(如Js和CSS文件),使浏览体验更快。我想避免Web视图缓存。是的,您可以使用shouldInterceptRequest()拦截远程url加载并返回本地存储的内容 WebView webview = (We

以前有人问过很多次,我浏览了所有的东西,还没有明确的答案

简化问题:是否可以将本地Javascript文件(从资产或存储)注入到Android Web视图中加载的远程网页?我知道可以将这些文件注入到Web视图中加载的本地网页(HTML资产)


为什么我需要这个来工作通过避免每次下载更大的文件(如Js和CSS文件),使浏览体验更快。我想避免Web视图缓存。

是的,您可以使用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);
       }
    }
});

有一种方法可以“强制”从本地资产(例如,assets/js/script.js)注入本地Javascript文件,并绕过“不允许加载本地资源:file:///android_assets/js/script.js ……问题

它类似于另一个线程()中描述的内容,具有额外的BASE64编码/解码,用于将Javascript文件表示为可打印字符串

我使用的是Android 4.4.2,API级别为19的虚拟设备

以下是一些代码片段:

[assets/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");

    ...

loadUrl将仅在旧版本中使用

webview.evaluateJavascript(((函数(){document.getElementsByName('username')[0]。value='username';document.getElementsByName('password')[0]。value='password'+
“return{var1:\'variable1\”,var2:\'variable2\”};();”,new ValueCallback(){
@凌驾
公共void onReceiveValue(字符串s){
Log.d(“LogName”,s);//打印:{“var1”:“variable1”,“var2”:“variable2”}
}
});

小心使用
evaluateJavascript
:如果javascript中出现语法错误或异常,它将使用null调用您的
onReceiveValue
。支持SDK 19和更低版本的最常见方式如下:

此外,如果您非常渴望某种浏览器功能(在我的情况下,永远无法找到如何让DRM正常工作),您可以在普通的chrome中使用bookmarklet,只有在omnibox中键入书签名称时,它才起作用,但确实起作用并注入javascript


还要注意,在默认的
WebView
中,您不能使用javascript警报来测试任何东西,它们不会显示。还要注意,默认情况下“视频”(如html标记)在默认情况下并不“真正起作用”,而且DRM视频在默认情况下也不起作用,它们都是配置选项:\

非常感谢,这很有效。然而,它只适用于高达4.3的android版本。对于Android 4.4,它说我必须只在UI线程内运行加载(loadUrl),当我使用RunOnUIThread()这样做时,它什么也不做,我的意思是它什么也不加载。你知道问题出在哪里吗?@sumit在Android 4.4中我使用
Runnable
对象如下:首先,我在类
MainActivity中定义
Handler
。。。{final Handler=new Handler();…
。其次,在我的方法中,我使用了一个
Runnable
对象,例如
void loadWebPage(){final Runnable r=new Runnable(){public void run(){WebView myWebView=…};Handler.post(r)}
。我希望这会有帮助。我也这么做了,但没有效果。原因是,在Kitkat版本中,无法使用view.loadUrl()在本地注入js文件。我必须使用evaluateJavaScript()方法,而且效果很好。要注入文件CSS文件,可以使用view.loadUrl(),但对于js,evaluateJavaScript()必须使用。欢迎使用ChromeView:)这是一个很棒的答案!我只有一个问题,它不适用于您要注入的UTF-8中的资产,并且超出ANSI字符范围。我可以通过将解码更改为:“script.innerHTML=decodeURIComponent(escape(window.atob(“+encoded+”);”+Genius-Genius!!!你救了我一天,兄弟!我已经发布了一个200悬赏的问题。如果你在下面发布答案,我可以接受你的答案。下面是链接:这是一个更好的解决方案,因为你可以更一致地运行Javascript。请注意,
shouldInterceptRequest(WebView,String)
已经被
shouldInterceptRequest取代(WebView,WebResourceRequest)
。此解决方案仍然有效(除了您必须检查
request.getUrl()
,并记住其类型为
Uri
)。另外请注意,如果您使用
WebView.loadData()
如果没有基本URL,则无法在
中使用相对路径,似乎
WebView
忽略了它们。请改用
loadDataWithBaseURL()
。什么是clientLogin?啊哈…WebView这需要minSdkVersion 19或更高版本。
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"}
                }
            });