2010-06-28 130 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