2010-06-28 19 views
32

C'è un modo per visualizzare le intestazioni delle risposte http in un'attività una volta che una pagina Web è stata caricata in una WebView? Sembra che questo dovrebbe essere possibile, ma non riesco a trovare alcun metodo che esponga le intestazioni.Accedere alle intestazioni delle risposte http in una WebView?

+1

No. Che cosa stai cercando di fare esattamente? Se si desidera esaminare la richiesta/risposta, è necessario effettuare la richiesta utilizzando HttpClient. –

+0

Sto provando a leggere un'intestazione della risposta http dalla pagina caricata nella mia WebView. Ho avuto la sensazione che avrei dovuto utilizzare HttpClient e quindi inviare la risposta al WebView. Più lavoro di quello che dovrebbe essere richiesto per leggere una risposta di intestazione ... – tronman

risposta

32

WebViewWebViewClient fornire metodi per farlo, Tuttavia, è possibile provare a implementarlo manualmente. Si può fare qualcosa di simile:

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(); 
    } 
} 

non posso provarlo in questo momento, ma questo è fondamentalmente ciò che si potrebbe fare (è molto pazzo però :).

+2

L'unico problema con questo metodo è che shouldOverrideUrlLoading() non viene chiamato quando si chiama loadUrl() di WebView. Questo è un grosso problema per me. – tronman

+1

Beh ... in questo caso devi solo sovrascrivere il metodo 'loadUrl()';) – Cristian

+0

Hai ragione. Questo * è * pazzo! –

1

Dovresti essere in grado di controllare tutte le intestazioni saltando loadUrl e scrivendo il tuo loadPage utilizzando l'HttpURLConnection di Java. Quindi visualizza le intestazioni, fai le tue cose e usa loadData della webview per visualizzare la risposta.

+1

Potresti per favore elaborare la tua risposta? Da 4 anni spero che ci sia un modo migliore per farlo. –

+2

@MW Apparentemente no. Forse nei prossimi 4 anni – Arthur

2

ispirato a Cristiananswer Avevo bisogno di intercettare le chiamate AJAX che sta facendo webview, dove dovevo intercettare le intestazioni di risposta per ottenere alcune informazioni (numero di elementi del carrello nell'app di e-commerce), che dovevo sfruttare in app. Poiché l'applicazione sta usando okhttp ho finito per fare questo e sta funzionando:

 @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; 
     } 

Spero che questo può essere utile per gli altri e se qualcuno ha un suggerimento per il miglioramento sarei grato. Sfortunatamente è compatibile solo con LOLLIPOP e versioni successive, poiché da questa versione è possibile accedere/restituire le intestazioni utilizzando WebResourceRequest, che era necessario per il mio caso.

+0

Non c'è alternativa a WebResourceRequest per le versioni precedenti di Android? Non è possibile catturare le richieste Ajax nelle vecchie versioni di Android? – Sohaib

+0

in alternativa è possibile utilizzare http://developer.android.com/guide/webapps/webview.html#BindingJavaScript se è possibile modificare ciò che sta facendo sito Web/webapp – ursimon

+0

Sto cercando di farlo anche su versioni precedenti di Android. Un modo per farlo? – clu

-2

come la risposta accettata funziona solo con HttpGet, ecco un trucco thet attualmente sto usando (in questo momento sembra funzionare)

In gestore onPageFinished, se si verifica un errore, il titolo di la pagina sarà come "ERROR_NUM - ERROR_DESCRIPTION", come "500 - Errore interno del server", quindi tutto quello che faccio è ottenere il titolo da webview nella funzione, e quindi controllare il titolo.

view.getTitle()

+0

Questo non ha nulla a che fare con ottenere le intestazioni di risposta. –

Problemi correlati