2010-06-28 176 views
32

有沒有一種方法可以在Web頁面中加載網頁後查看活動中的http響應頭文件?似乎這應該是可能的,但我找不到任何公開頭的方法。訪問WebView中的http響應標頭?

+1

不,你究竟在做什麼?如果你想看看請求/響應,你將不得不使用HttpClient進行請求。 – 2010-06-28 17:13:14

+0

我想從我的WebView中加載的頁面讀取http響應頭。我有一種感覺,我將不得不使用HttpClient,然後將響應發送回WebView。讀取標題響應所需的工作量應該超過... – tronman 2010-06-28 17:23:50

回答

32

WebViewWebViewClient都沒有提供這樣做的方法,但是,您可以嘗試手動實現該方法。你可以這樣做:

private WebView webview; 
public void onCreate(Bundle icicle){ 
    // bla bla bla 

    // here you initialize your webview 
    webview = new WebView(this); 
    webview.setWebViewClient(new YourWebClient()); 
} 

// this will be the webclient that will manage the webview 
private class YourWebClient extends WebViewClient{ 

    // you want to catch when an URL is going to be loaded 
    public boolean shouldOverrideUrlLoading (WebView view, String urlConection){ 
     // here you will use the url to access the headers. 
     // in this case, the Content-Length one 
     URL url; 
     URLConnection conexion; 
     try { 
      url = new URL(urlConection); 
      conexion = url.openConnection(); 
      conexion.setConnectTimeout(3000); 
      conexion.connect(); 
      // get the size of the file which is in the header of the request 
      int size = conexion.getContentLength(); 
     } 


     // and here, if you want, you can load the page normally 
     String htmlContent = ""; 
     HttpGet httpGet = new HttpGet(urlConection); 
     // this receives the response 
     HttpResponse response; 
     try { 
      response = httpClient.execute(httpGet); 
      if (response.getStatusLine().getStatusCode() == 200) { 
       // la conexion fue establecida, obtener el contenido 
       HttpEntity entity = response.getEntity(); 
       if (entity != null) { 
        InputStream inputStream = entity.getContent(); 
        htmlContent = convertToString(inputStream); 
       } 
      } 
     } catch (Exception e) {} 

     webview.loadData(htmlContent, "text/html", "utf-8"); 
     return true; 
    } 

    public String convertToString(InputStream inputStream){ 
     StringBuffer string = new StringBuffer(); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 
     String line; 
     try { 
      while ((line = reader.readLine()) != null) { 
       string.append(linea + "\n"); 
      } 
     } catch (IOException e) {} 
     return string.toString(); 
    } 
} 

我現在不能測試它,但基本上你可以做(​​雖然它很瘋狂:)。

+2

此方法的唯一問題是在調用WebView的loadUrl()時,不會調用shouldOverrideUrlLoading()。這對我來說是個大問題。 – tronman 2010-06-28 19:00:27

+1

那麼......在這種情況下,你只需要重載'loadUrl()'方法;) – Cristian 2010-06-28 19:21:53

+0

你是對的。這很瘋狂! – 2013-09-11 15:50:41

1

您應該能夠通過跳過loadUrl並使用Java的HttpURLConnection編寫自己的loadPage來控制所有的頭文件。然後查看標題,做你的事情,並使用webview的loadData來顯示響應。

+1

請您詳細說明您的答案?自從4年來,我希望有更好的方法去做。 – 2015-05-20 15:14:54

+2

@MW顯然不是。也許在未來4年 – Arthur 2016-07-11 13:34:48

2

靈感來自Cristiananswer我需要攔截AJAX調用webview正在做的事情,我需要攔截響應頭以獲取一些信息(電子商務應用程序中的購物車項數),我需要在應用程序中利用這些信息。當應用程序使用okhttp我已經結束了這樣做的,它的工作

 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
     @Override 
     public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { 
      Log.i(TAG,"shouldInterceptRequest path:"+request.getUrl().getPath()); 
      WebResourceResponse returnResponse = null; 
      if (request.getUrl().getPath().startsWith("/cart")) { // only interested in /cart requests 
       returnResponse = super.shouldInterceptRequest(view, request); 
       Log.i(TAG,"cart AJAX call - doing okRequest"); 
       Request okRequest = new Request.Builder() 
         .url(request.getUrl().toString()) 
         .post(null) 
         .build(); 
       try { 
        Response okResponse = app.getOkHttpClient().newCall(okRequest).execute(); 
        if (okResponse!=null) { 
         int statusCode = okResponse.code(); 
         String encoding = "UTF-8"; 
         String mimeType = "application/json"; 
         String reasonPhrase = "OK"; 
         Map<String,String> responseHeaders = new HashMap<String,String>(); 
         if (okResponse.headers()!=null) { 
          if (okResponse.headers().size()>0) { 
           for (int i = 0; i < okResponse.headers().size(); i++) { 
            String key = okResponse.headers().name(i); 
            String value = okResponse.headers().value(i); 
            responseHeaders.put(key, value); 
            if (key.toLowerCase().contains("x-cart-itemcount")) { 
             Log.i(TAG,"setting cart item count"); 
             app.setCartItemsCount(Integer.parseInt(value)); 
            } 
           } 
          } 
         } 
         InputStream data = new ByteArrayInputStream(okResponse.body().string().getBytes(StandardCharsets.UTF_8)); 
         Log.i(TAG, "okResponse code:" + okResponse.code()); 
         returnResponse = new WebResourceResponse(mimeType,encoding,statusCode,reasonPhrase,responseHeaders,data); 
        } else { 
         Log.w(TAG,"okResponse fail"); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      return returnResponse; 
     } 

我希望這可能是幫助他人,如果有人有改善的建議,我將不勝感激。不幸的是,它僅與LOLLIPOP兼容,從此版本起,您可以使用WebResourceRequest訪問/返回標頭,這是我的情況所需要的。

+0

對於舊的Android版本,WebResourceRequest是否沒有其他選擇?是不是可以在較舊的Android版本中捕獲Ajax請求? – Sohaib 2015-03-31 10:19:35

+0

或者您可以使用http://developer.android.com/guide/webapps/webview.html#BindingJavaScript,如果您可以更改網站/ webapp正在做什麼 – ursimon 2015-05-22 13:03:12

+0

我正試圖在舊版本的Android上進行此操作。任何方式來做到這一點? – clu 2016-03-18 18:47:39

-2

作爲公認的答案將只與HTTPGET工作,這裏是一招泰德我目前使用(在這個時候似乎工作)

在onPageFinished處理程序,如果有錯誤,稱號該頁面將像「ERROR_NUM - ERROR_DESCRIPTION」一樣,如「500 - 內部服務器錯誤」,所以我所做的只是從webview中獲取標題的功能,然後檢查標題。

view.getTitle()

+0

這與獲取響應標題沒有任何關係。 – 2017-11-04 18:17:37