2017-01-26 9 views
6

ja przechwytując żądania z WebView użyciu shouldInterceptRequestAndroid: WebView shouldInterceptRequest nie dodając RequestProperties w WebView

poniżej jest mój kod powrocie mój WebResourceResponse

@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    private static WebResourceResponse handleRequestViaUrlOnly(WebResourceRequest webResourceRequest){ 
     String url = webResourceRequest.getUrl().toString(); 
     Log.i("intercepting req....!!!", url); 
     String ext = MimeTypeMap.getFileExtensionFromUrl(url); 
     String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext); 

     try { 
      HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); 
      conn.setRequestProperty("Sample-Header", "hello"); 
      conn.setDoOutput(true); 
      conn.setDoInput(true); 
      conn.setUseCaches(false); 
      return new WebResourceResponse(mime, "UTF-8", conn.getInputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

nazywam tę metodę w moim CustomWebViewClient

class CustomWebViewClient extends WebViewClient { 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    @Override 
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { 
     return handleRequestViaUrlOnly(request); 
    } 
} 

Jednak, gdy sprawdzam nagłówki żądań z zdalnego debugera WebView w chrome: // inspect/# pomysłowość.

Dodatkowa prośba o przyznanie, którą dodałem, nie jest obecna.

conn.setRequestProperty("Sample-Header", "hello"); 

Nagłówek próbki nie występuje w nagłówkach zgłoszeń w WebView.

Czy brakuje mi czegoś? Docenię każdą pomoc.

+0

Dose idzie w IO bloku wyjątków? –

+0

nie, ale wywołanie tego nowego adresu URL (url) .openConnection() wymaga przechwycenia wyjątku IOException. – Aaron

+0

Po prostu zaksięguj pełny kod wywoływania tej metody? –

Odpowiedz

0

Problem polega na tym, że podczas przekazywania conn.getInputStream() podaje tylko dane. Nagłówki odpowiedzi można wyodrębnić za pomocą conn.getHeaderFields(). Ponadto nie będzie można odzyskać dodatkowego nagłówka, chyba że serwer go obsługuje i CORS nie uczestniczy. Oto wireshark wyjściowym połączenia

GET /~fdc/sample.html HTTP/1.1 
Sample-Header: hello 
Content-Type: application/x-www-form-urlencoded 
User-Agent: Dalvik/2.1.0 (Linux; U; Android 7.1; Android SDK built for x86_64 Build/NPF26K) 
Host: www.columbia.edu 
Connection: Keep-Alive 
Accept-Encoding: gzip 
Content-Length: 0 

HTTP/1.1 200 OK 
Date: Wed, 01 Mar 2017 09:06:58 GMT 
Server: Apache 
Last-Modified: Thu, 22 Apr 2004 15:52:25 GMT 
Accept-Ranges: bytes 
Vary: Accept-Encoding,User-Agent 
Content-Encoding: gzip 
Content-Length: 8664 
Keep-Alive: timeout=15, max=99 
Connection: Keep-Alive 
Content-Type: text/html 

Jak widać nie ma Sample-Header: hello nagłówek w odpowiedzi.

Oto prosty kod, który wybuduje WebResourceResponse nagłówki z odpowiedzią i dołączyć swój własny nagłówek do niego:

webView.setWebViewClient(new WebViewClient() { 
    private Map<String, String> convertResponseHeaders(Map<String, List<String>> headers) { 
     Map<String, String> responseHeaders = new HashMap<>(); 
     responseHeaders.put("Sample-Header", "hello"); 

     for (Map.Entry<String, List<String>> item : headers.entrySet()) { 
      List<String> values = new ArrayList<String>(); 

      for (String headerVal : item.getValue()) { 
       values.add(headerVal); 
      } 
      String value = StringUtil.join(values, ","); 
      Log.e(TAG, "processRequest: " + item.getKey() + " : " + value); 

      responseHeaders.put(item.getKey(), value); 
     } 

     return responseHeaders; 
    } 

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 
    @Override 
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { 
     final String method = request.getMethod(); 
     final String url = request.getUrl().toString(); 
     Log.d(TAG, "processRequest: " + url + " method " + method); 
     String ext = MimeTypeMap.getFileExtensionFromUrl(url); 
     String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext); 

     try { 
      HttpURLConnection conn = (HttpURLConnection)new URL(url).openConnection(); 
      conn.setRequestMethod(method); 
      conn.setRequestProperty("Sample-Header", "hello"); 
      conn.setDoInput(true); 
      conn.setUseCaches(false); 

      Map<String, String> responseHeaders = convertResponseHeaders(conn.getHeaderFields()); 

      responseHeaders.put("Sample-Header", "hello"); 

      return new WebResourceResponse(
        mime, 
        conn.getContentEncoding(), 
        conn.getResponseCode(), 
        conn.getResponseMessage(), 
        responseHeaders, 
        conn.getInputStream() 
        ); 

     } catch (Exception e) { 
      Log.e(TAG, "shouldInterceptRequest: " + e); 
     } 
     return null; 
    } 
}); 
+0

Mam również kod taki jak ten, tak, otrzymuję nagłówki odpowiedzi, a moim problemem są nagłówki żądań. Nie mogę dodać nagłówków żądań do mojej przeglądarki internetowej. także jeśli loguję nagłówki żądań po dodaniu jednego, dostaję je w logach, jednak kiedy dojdzie do widoku web, to nie jest obecne, – Aaron

+0

Więc próbujesz zmodyfikować webResourceReqest i co ta zmiana ma być odzwierciedlona po stronie javascript w przeglądarka internetowa? – j2ko