2011-01-24 74 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; 
}