使用 android 中的 webview 将 javascript 文件注入我的网站

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30036907/
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-28 11:32:04  来源:igfitidea点击:

Inject javascript file to my site with webview in android

javascriptandroidwebviewwebkit

提问by sinaamiri

I want to inject javascriptfile to my site. My site is a simple htmlpage that is on server. I have injected cssfile. (with Manish's help)

我想将javascript文件注入我的网站。我的网站是一个html位于服务器上的简单页面。我已经注入css文件。(在 Manish 的帮助下

So I can manage my simple htmlsite with CSSnow. But I want to manage it with javascripttoo. My jscript.jsfile is in assetfolder. I want to have full access of javascripton my site. (Remember that, it is MY site) . please write the correct codes for me. Thankx.

所以我现在可以管理我的简单 html网站CSS。但我也想管理它javascript。我的jscript.js文件在asset文件夹中。我想javascript在我的网站上拥有完全访问权限。(请记住,这是我的网站)。请为我写正确的代码。谢谢。

Here is my MainActivity.javafile:

这是我的MainActivity.java文件:

package com.example.z5070.myapplication;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Base64;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.InputStream;


public class MainActivity extends ActionBarActivity {



        WebView webView;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            webView = new WebView(this);
            setContentView(webView);


            webView.getSettings().setJavaScriptEnabled(true);


            webView.setWebViewClient(new WebViewClient() {

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


                    injectCSS();
                    super.onPageFinished(view, url);
                }
            });


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


        private void injectCSS() {
            try {
                InputStream inputStream = getAssets().open("style.css");
                byte[] buffer = new byte[inputStream.available()];
                inputStream.read(buffer);
                inputStream.close();
                String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
                webView.loadUrl("javascript:(function() {" +
                        "var parent = document.getElementsByTagName('head').item(0);" +
                        "var style = document.createElement('style');" +
                        "style.type = 'text/css';" +
                        "style.innerHTML = window.atob('" + encoded + "');" +
                        "parent.appendChild(style)" +
                        "})()");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {

            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            int id = item.getItemId();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }


        }

回答by Manish Raj

Add a new method to inject javascript file.

添加一个新方法来注入 javascript 文件。

 private void injectJS() {
        try {
            InputStream inputStream = getAssets().open("jscript.js");
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);
            inputStream.close();
            String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
            webView.loadUrl("javascript:(function() {" +
                    "var parent = document.getElementsByTagName('head').item(0);" +
                    "var script = document.createElement('script');" +
                    "script.type = 'text/javascript';" +
                    "script.innerHTML = window.atob('" + encoded + "');" +
                    "parent.appendChild(script)" +
                    "})()");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Call both methods: injectCSS() and injectJS() after page finishes loading.

在页面加载完成后调用这两种方法:injectCSS() 和 injectJS()。

webView.setWebViewClient(new WebViewClient() {

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

I hope this solves the problem.

我希望这能解决问题。

Be wary of how onload events defined inside inject js file would behave.

请注意在注入 js 文件中定义的 onload 事件的行为方式。

回答by yuliskov

Some refinements to previous answer. Suppose we use Cyrillic words. Result would be a garbaged strings. It's not good. With code below you can use non-english chars in content. Just add additional url-encoding/decoding to your code and you good to go. Reedited version below.

对先前答案的一些改进。假设我们使用西里尔字母。结果将是一个垃圾字符串。这样不好。使用下面的代码,您可以在内容中使用非英文字符。只需在您的代码中添加额外的 url-encoding/decoding 即可。下面重新编辑的版本。

private void injectJS() {
    try {
        InputStream inputStream = getAssets().open("jscript.js");
        byte[] buffer = new byte[inputStream.available()];
        inputStream.read(buffer);
        inputStream.close();

        // preserve non-english letters
        String uriEncoded = URLEncoder.encode(new String(buffer, "UTF-8"), "UTF-8").replace("+", "%20");

        String encoded = Base64.encodeToString(uriEncoded.getBytes(), Base64.NO_WRAP);
        webView.loadUrl("javascript:(function() {" +
                "var parent = document.getElementsByTagName('head').item(0);" +
                "var script = document.createElement('script');" +
                "script.type = 'text/javascript';" +
                // don't forget to use decodeURIComponent after base64 decoding
                "script.innerHTML = decodeURIComponent(window.atob('" + encoded + "'));" +
                "parent.appendChild(script)" +
                "})()");
    } catch (Exception e) {
        e.printStackTrace();
    }
}