Доступ к заголовкам ответа HTTP в WebView? - PullRequest
36 голосов
/ 28 июня 2010

Есть ли способ просмотреть заголовки ответа http в Activity после загрузки веб-страницы в WebView?Похоже, это должно быть возможно, но я не могу найти какие-либо методы, которые выставляют заголовки.

Ответы [ 4 ]

32 голосов
/ 28 июня 2010

Ни WebView, ни WebViewClient не предоставляют методов для этого, хотя вы можете попробовать реализовать это вручную.Вы можете сделать что-то вроде этого:

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 голосов
/ 18 февраля 2015

вдохновлено Кристианом ответом Мне нужно было перехватить вызовы AJAX, которые выполняет веб-просмотр, где мне нужно было перехватить заголовки ответа, чтобы получить некоторую информацию (количество элементов корзины в приложении электронной торговли) , который мне нужно было использовать в приложении. Поскольку приложение использует 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 , что было необходимо для моего случая.

1 голос
/ 12 февраля 2014

Вы должны иметь возможность контролировать все свои заголовки, пропустив loadUrl и написав свой собственный loadPage, используя Java HttpURLConnection. Затем просмотрите заголовки, сделайте свое дело и используйте loadData веб-просмотра для отображения ответа.

0 голосов
/ 07 февраля 2017

Поскольку принятый ответ будет работать только с HttpGet, вот трюк, который я сейчас использую (в настоящее время он работает)

В обработчике onPageFinished, если есть ошибка, заголовок страницы будет выглядеть как «ERROR_NUM - ERROR_DESCRIPTION», как «500 - Внутренняя ошибка сервера», поэтому все, что я делаю, это чтобы получить заголовок из веб-просмотра в функции, а затем проверьте название.

view.getTitle ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...