2011-01-24 177 views
52

我在我的应用程序中打开了一些网站(总是相同的,它是我自己的网页)中的WebView。该网站有一些JS代码从远程主机加载一些图像。拦截并覆盖来自WebView的HTTP请求

我想拦截对这些图像的请求(通过URL模式)并返回我自己的内容(即另一图像),或者根据内部应用程序逻辑保留请求不变。

有没有可能这样做?

EDIT:问题的当前状态...

WebView具有设置的能力的WebViewClient(如由Axarydax说明)。 WebViewClient有两个有用的方法

  • shouldOverrideUrlLoading
  • onLoadResource

shouldOverrideUrlLoading能够拦截任何URL负载,负载是通过网页的交互触发(即页面上的链接被点击,WebView.loadURL (“”)不会触发此方法)。它也可以通过返回false来取消URL加载。这种方法是不可用的,因为'它不能拦截加载页面资源(和图像,我需要拦截,是这样一个页面资源)。

onLoadResource每当页面资源(和images!thx to jessyjones)被加载时触发,但是没有办法取消它。这使得这种方法也不适合我的任务。

webView.setWebViewClient(new WebViewClient() { 
    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url) { 
     if (url.startsWith("foo://")) { 
      // magic 
      return true; 
     } 
     return false; 
    } 
}); 

回答

63

试试这个,我已经在个人wiki的应用程序使用它方法是

@Override public void onLoadResource(WebView view, String url)

这种方法被称为为所有资源(图片,styleesheet,脚本)这是由web视图加载,但因为它是一个空白,我还没有找到一种方法来改变URL和替换它会加载本地资源...

+0

好吧,这是拦截调用的方式(顺便说一句,如果我的网页加载一个图像,而不是做一个完整的重新加载它会触发?),但我如何提供由我的Java代码生成的拦截调用的响应? – Olegas 2011-01-26 14:54:54

+1

您可以使用WebView的loadData()方法将一些html推入其中。用法:webView.loadData(“ ...”,“text/html”,“utf-8”); – Axarydax 2011-01-28 13:57:42

+0

不适用。通过loadData加载的静态内容无法访问通过网络加载的其他内容。作为解决方法loadData(“javascript:....”)可用于(与某些“客户”代码交互)。如果为每个页面资源(完全内容图像)调用shouldOverrideUrlLoading,这可能是一个很好且适合的问题。但事实并非如此。 – Olegas 2011-01-29 10:29:51

10

据我所知,shouldOverrideUrlLoading不会调用图像,而是超链接...我认为合适的:

8

这是我用于我的应用程序的解决方案。

我有几个资产文件夹与css/js/img anf字体文件。

应用程序获取所有文件名并查看是否请求具有该名称的文件。如果是,则从资产文件夹加载它。

//get list of files of specific asset folder 
     private ArrayList listAssetFiles(String path) { 

      List myArrayList = new ArrayList(); 
      String [] list; 
      try { 
       list = getAssets().list(path); 
       for(String f1 : list){ 
        myArrayList.add(f1); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return (ArrayList) myArrayList; 
     } 

     //get mime type by url 
     public String getMimeType(String url) { 
      String type = null; 
      String extension = MimeTypeMap.getFileExtensionFromUrl(url); 
      if (extension != null) { 
       if (extension.equals("js")) { 
        return "text/javascript"; 
       } 
       else if (extension.equals("woff")) { 
        return "application/font-woff"; 
       } 
       else if (extension.equals("woff2")) { 
        return "application/font-woff2"; 
       } 
       else if (extension.equals("ttf")) { 
        return "application/x-font-ttf"; 
       } 
       else if (extension.equals("eot")) { 
        return "application/vnd.ms-fontobject"; 
       } 
       else if (extension.equals("svg")) { 
        return "image/svg+xml"; 
       } 
       type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); 
      } 
      return type; 
     } 

     //return webresourceresponse 
     public WebResourceResponse loadFilesFromAssetFolder (String folder, String url) { 
      List myArrayList = listAssetFiles(folder); 
      for (Object str : myArrayList) { 
       if (url.contains((CharSequence) str)) { 
        try { 
         Log.i(TAG2, "File:" + str); 
         Log.i(TAG2, "MIME:" + getMimeType(url)); 
         return new WebResourceResponse(getMimeType(url), "UTF-8", getAssets().open(String.valueOf(folder+"/" + str))); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
      return null; 
     } 

     //@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
     @SuppressLint("NewApi") 
     @Override 
     public WebResourceResponse shouldInterceptRequest(final WebView view, String url) { 
      //Log.i(TAG2, "SHOULD OVERRIDE INIT"); 
      //String url = webResourceRequest.getUrl().toString(); 
      String extension = MimeTypeMap.getFileExtensionFromUrl(url); 
      //I have some folders for files with the same extension 
      if (extension.equals("css") || extension.equals("js") || extension.equals("img")) { 
       return loadFilesFromAssetFolder(extension, url); 
      } 
      //more possible extensions for font folder 
      if (extension.equals("woff") || extension.equals("woff2") || extension.equals("ttf") || extension.equals("svg") || extension.equals("eot")) { 
       return loadFilesFromAssetFolder("font", url); 
      } 

      return null; 
     } 
0

这可能帮助:

@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
@Override 
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { 
    String url = request.getUrl().toString(); 
    WebResourceResponse response = super.shouldInterceptRequest(view, request); 
    // load native js 
    if (url != null && url.contains(INJECTION_TOKEN/* scheme define */)) { 

     response = new WebResourceResponse(
       "text/javascript", 
       "utf-8", 
       loadJsInputStream(url, JsCache.getJsFilePath(path) /* InputStream */)); 
    } 
    return response; 
}