Android WebView 在加载 html 之前注入 Javascript

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14064589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:37:37  来源:igfitidea点击:

Android WebView Inject Javascript before html loaded

javascriptandroidwebview

提问by wayne_bai

I am using Android WebView to load some web pages. I need insert a piece of Javascript code to all the pages before they loaded.

我正在使用 Android WebView 加载一些网页。我需要在所有页面加载之前插入一段 Javascript 代码。

I am trying to inject them on WebViewClient onPageStart callback.

我试图将它们注入 WebViewClient onPageStart 回调。

mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient(){

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        loadUrl("javascript:var output='test string';");
        }
})

mWebView.loadUrl("xxx.html");

HTML code:

HTML代码:

<html>
<script>document.write(output);</script>
</html>

I expected My Js code loaded before HTML. But sometimes the JS code loaded after HTML.

我希望在 HTML 之前加载我的 Js 代码。但有时 JS 代码在 HTML 之后加载。

Is there any way could solve my issue?

有什么办法可以解决我的问题吗?

回答by sagus_helgy

I had the same problem and I solved it. I hide WebViewbefore load and show after page loaded.

我有同样的问题,我解决了它。我WebView在加载前隐藏并在页面加载后显示。

webView.getSettings().setJavaScriptEnabled(true);
b.webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        return false;
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            b.webView.evaluateJavascript("javascript:window.document.getElementsByTagName('body')[0].style.color='white';", null);
        }
        else
        {
            b.webView.loadUrl("javascript:window.document.getElementsByTagName('body')[0].style.color='white';");
        }
        b.webView.setVisibility(View.VISIBLE);
    }

});

b.webView.setVisibility(View.INVISIBLE);
b.webView.loadUrl(PreferenceHelper.EULA_URL);

回答by Thomas

What about loading your page via javascript ?

如何通过 javascript 加载您的页面?

Create a blank html page in your assets, that include your script plus this little function (I'm using jquery for the sake of simplicity here, but you can use another framework or not framework at all).

在您的资产中创建一个空白的 html 页面,其中包括您的脚本和这个小功能(为了简单起见,我在这里使用 jquery,但您可以使用其他框架或根本不使用框架)。

window.loadPage = function (url) {
    $.get(url, function(page) {
        $('html').replace(page);
    });
};

Then, on your android app :

然后,在你的安卓应用上:

mWebView.loadUrl("javascript: loadPage('xxx.html')");

Note : I didn't notice xxx.html could be in your assets too and not in a web server somewhere, in that case the ajax query will fail for security reasons, but you can forget the ajax request, read you html page in String from your android app and pass it as an argument to a slightly modified javascript function.

注意:我没有注意到 xxx.html 也可能在您的资产中,而不是在某个 Web 服务器中,在这种情况下,出于安全原因,ajax 查询将失败,但您可以忘记 ajax 请求,读取字符串中的 html 页面从您的 android 应用程序并将其作为参数传递给稍作修改的 javascript 函数。

回答by ankuranurag2

You can inject your javascript before page loading like this:

您可以在页面加载之前注入您的 javascript,如下所示:

  val mimeType = "text/html"
  val encoding = "utf-8"
  val injection = "<script type='text/javascript'>
        //Your JavaScript code here

       //**This line is important**
        "window.location.replace('ACTUAL_URL');</script>"
  webView.loadDataWithBaseURL('ANY_DUMMY_URL', injection, mimeType, encoding, null)

The ACTUAL_URL should be URL you actually want to load. DUMMY_URL can be any URL, better keep it same as ACTUAL_URL.

ACTUAL_URL 应该是您实际想要加载的 URL。DUMMY_URL 可以是任何 URL,最好与 ACTUAL_URL 保持一致。

回答by Catalina T.

I had to do the same as you, since, in my case, the loading of the web page depended on some variables that needed to be set from the app through JavaScript.

我必须和你做同样的事情,因为在我的情况下,网页的加载取决于一些需要通过 JavaScript 从应用程序设置的变量。

After trying all the different permutations for loading the javascript before the page loads, this is what finally worked for me:

在页面加载之前尝试了所有不同的排列来加载 javascript 之后,这最终对我有用:

webView.loadUrl(url)
webView.settings.javaScriptEnabled = true
webView.settings.javaScriptCanOpenWindowsAutomatically = true

val javascript = "alert('some javascript message');window.JAVASCRIPT_GLOBAL_VARIABLE=true;"

webView.webViewClient = object : WebViewClient() {
    override fun onLoadResource(view: WebView?, url: String?) {
         super.onLoadResource(view, url)
         webView.evaluateJavascript(javascript) {}
    }    
}

If you need your javascript injected variables or methods to be available when the web view loads - for example, to authenticate the user, I had to also add the following to the javascript code to make it work reliably, every single time you open the web view.

如果你需要你的 javascript 注入的变量或方法在 web 视图加载时可用 - 例如,为了验证用户,我还必须将以下内容添加到 javascript 代码中,以使其在每次打开 web 时可靠地工作看法。

window.location.replace('$url'); \ this is the same url you want to inject the javascript into

Using the addJavascriptInterfaceonly works if you want/can append some prefix to your Javascript methods. In my case, this was not an option since the same code should work for iOS as well.

addJavascriptInterface如果您想要/可以在您的 Javascript 方法中附加一些前缀,则使用only 有效。就我而言,这不是一个选项,因为相同的代码也适用于 iOS。

回答by SharpZhang

You can use
webView.addJavascriptInterface("test string", "output");
to inject the object you want, before the web page loaded.

您可以使用
webView.addJavascriptInterface("test string", "output");
在网页加载之前注入您想要的对象。

回答by Bhavdip Sagar

you can try to put your java script inside html page then use android java script function call might be helpful

您可以尝试将您的 java 脚本放在 html 页面中,然后使用 android java 脚本函数调用可能会有所帮助

回答by yoah

One way, maybe not the most simple, is to use an HttpClient to read the data from the web server yourself, and then modify it and set it into the webview using

一种方法,也许不是最简单的,是使用 HttpClient 自己从 web 服务器读取数据,然后修改它并使用

webview.loadData(mydata, "text/html", null);

回答by luisfer

I would use a combination of Phonegap and an interface for JavaScript.

我会结合使用 Phonegap 和 JavaScript 接口。

In the main .java file, in OnCreate(), include this:

在主 .java 文件的 OnCreate() 中,包含以下内容:

super.appView.addJavascriptInterface(new Object()
        {
          public void setOutput()
          {
            // here the body of your method in Android
          }
        }, "myInterface");

And then, in the .js file, include this (you have to import Phonegap in the same file, obviously, to catch the onDeviceReady method):

然后,在 .js 文件中,包含以下内容(显然,您必须在同一文件中导入 Phonegap,以捕获 onDeviceReady 方法):

function onDeviceReady() {
        myInterface.setOutput();
      }

This would trigger your method from JavaScript when the device is ready, during the first moment of the launch of the application.

这将在设备准备就绪时,在应用程序启动的第一时刻从 JavaScript 触发您的方法。