Android webview,在assets文件夹中加载javascript文件 [英] Android webview, loading javascript file in assets folder

查看:76
本文介绍了Android webview,在assets文件夹中加载javascript文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到这个问题被问了很多次,但仍然无法让我的代码正常工作.

I've seen this question has been asked a lot of times, but still can't manage to get my code working.

我希望我的 webview 加载一些 URL(比如 www.google.com),然后应用一些存储在 assets/jstest.js 中的 javascript,其中包含以下内容:

I want my webview to load some URL (say www.google.com) and then apply some javascript stored in assets/jstest.js, which contains the following:

function test(){
document.bgColor="#00FF00"; //turns to green the background color
}

这里是我尝试加载 JS 的地方:

And here's where I try to load the JS:

@Override  
public void onPageFinished(WebView view, String url){
    view.loadUrl("javascript:(function() { "
                + " document.bgColor='#FF0000';" //turns to red the background color
                + " var script=document.createElement('script'); "
                + " script.setAttribute('type','text/javascript'); "
                + " script.setAttribute('src', 'file:///android_asset/jstest.js'); "
                + " script.onload = function(){ "
                + "     test(); "
                + " }; "
                + " document.getElementsByTagName('head')[0].appendChild(script); "
                + "})()"); 
} 

我知道这里的 javascript 可以工作,因为背景颜色实际上变成了红色,但由于某种原因它不会加载 jstest.js.我认为问题可能出在文件路径中(我确定 javascript 代码的其他每一行都是正确的),但对我来说它看起来是正确的.并且该文件位于正确的文件夹中.

I know the javascript here works because the background color actually turns to red, but for some reason it won't load jstest.js. I think the problem might be in file path (I'm certain every other line of the javascript code is correct), but it looks correct to me. And the file is in the right folder.

我错过了什么?

编辑:

由于 WebResourceResponse 类仅适用于 API 级别 11,这就是我最后想到的.

Since WebResourceResponse class is available only with API Level 11, here's what I've figured out in the end.

public void onPageFinished(WebView view, String url){
        String jscontent = "";
        try{
            InputStream is = am.open("jstest.js"); //am = Activity.getAssets()
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

            String line;
            while (( line = br.readLine()) != null) {
                jscontent += line;
            }
            is.close(); 
        }
        catch(Exception e){}
        view.loadUrl("javascript:(" + jscontent + ")()"); 
    } 

使用 jstest.js 简单地包含:

function() {
    document.bgColor="#00FF00";
}

推荐答案

我尝试了同样的事情,将书签(loadUrl() 调用中的 javascript 代码)加载到第三方页面中.我的书签还依赖于其他资产(javascript 和 css 文件),这些资产不会通过 file:///android_asset URL 加载.

I tried the same thing, loading a bookmarklet (the javascript code in your loadUrl() call) into a third-party page. My bookmarklet also depends on other assets (javascript and css files) which would not load with a file:///android_asset URL.

那是因为页面的安全上下文仍然是,例如 http://www.google.com,并且不允许访问 file: URL.如果您提供/覆盖 WebChromeClient.onConsoleMessage(),您应该能够看到错误.

That's because the security context of the page is still that of, e.g., http://www.google.com, and that's not allowed access to file: URLs. You should be able to see the errors if you supply/override a WebChromeClient.onConsoleMessage().

我最终搞砸了,我将书签的资产引用更改为虚假 URL 方案,例如:

I ended up with a kludge where I changed the bookmarklet's asset references to a bogus URL scheme, like:

asset:foo/bar/baz.js

并添加了一个 WebViewClient.shouldInterceptRequest() 覆盖,用于查找这些并使用 AssetManager.open() 从资产中加载它们.

and added a WebViewClient.shouldInterceptRequest() override which looks for those and loads them from assets using AssetManager.open().

我不喜欢这个组合的一件事是资产:方案对我的视图加载的任何页面上的任何第三方 HTML/Javascript 开放,让他们可以访问我的应用程序的资产.

One thing I don't like about this kludge is that the asset: scheme is open to any third-party HTML/Javascript on any page my view loads, giving them access to my app's assets.

我没有尝试过的另一种方法是使用 data: URL 将子资产嵌入书签中,但这会变得很笨拙.

One alternative, which I didn't try, would be to embed the sub-assets in the bookmarklet using data: URLs, but that can get unwieldy.

如果有一种方法可以操纵我在 loadUrl() 中加载的 JS 书签的只是的安全上下文,我更喜欢它,但我找不到类似的东西.

I'd much prefer it if there was a way to manipulate the security context of just the JS bookmarklet I'm loading in loadUrl(), but I can't find anything like that.

这是一个片段:

import android.webkit.WebResourceResponse;
...
    private final class FooViewClient extends WebViewClient
    {
    private final String bookmarklet;
    private final String scheme;

    private FooViewClient(String bookmarklet, String scheme)
        {
        this.bookmarklet = bookmarklet;
        this.scheme = scheme;
        }

    @Override
    public void onPageFinished(WebView view, String url)
        {
        view.loadUrl(bookmarklet);
        }

    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url)
        {
        if (url.startsWith(scheme))
            try
                {
                return new WebResourceResponse(url.endsWith("js") ? "text/javascript" : "text/css", "utf-8",
                        Foo.this.getAssets().open(url.substring(scheme.length())));
                }
            catch (IOException e)
                {
                Log.e(getClass().getSimpleName(), e.getMessage(), e);
                }

        return null;
        }
    }

这篇关于Android webview,在assets文件夹中加载javascript文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆