Добавление пользовательских заголовков в запросы ресурсов WebView - андроид

Мне нужно добавить пользовательские заголовки для КАЖДОГО запроса, поступающего из WebView. Я знаю, что loadURL имеет параметр для extraHeaders, но они применяются только к первоначальному запросу. Все последующие запросы не содержат заголовков. Я просмотрел все переопределения в WebViewClient, но ничто не позволяет добавлять заголовки к запросам ресурсов - onLoadResource(WebView view, String url). Любая помощь будет замечательной.

Спасибо, Рэй

Ответ 1

Попробуйте

loadUrl(String url, Map<String, String> extraHeaders)

Для добавления заголовков в запросы загрузки ресурсов создайте пользовательский WebViewClient и переопределите:

API 24+:
WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
or
WebResourceResponse shouldInterceptRequest(WebView view, String url)

Ответ 2

Вам нужно будет перехватить каждый запрос, используя WebViewClient.shouldInterceptRequest

При каждом перехвате вам нужно будет взять URL-адрес, сделать этот запрос самостоятельно и вернуть поток контента:

WebViewClient wvc = new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

        try {
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            httpGet.setHeader("MY-CUSTOM-HEADER", "header value");
            httpGet.setHeader(HttpHeaders.USER_AGENT, "custom user-agent");
            HttpResponse httpReponse = client.execute(httpGet);

            Header contentType = httpReponse.getEntity().getContentType();
            Header encoding = httpReponse.getEntity().getContentEncoding();
            InputStream responseInputStream = httpReponse.getEntity().getContent();

            String contentTypeValue = null;
            String encodingValue = null;
            if (contentType != null) {
                contentTypeValue = contentType.getValue();
            }
            if (encoding != null) {
                encodingValue = encoding.getValue();
            }
            return new WebResourceResponse(contentTypeValue, encodingValue, responseInputStream);
        } catch (ClientProtocolException e) {
            //return null to tell WebView we failed to fetch it WebView should try again.
            return null;
        } catch (IOException e) {
             //return null to tell WebView we failed to fetch it WebView should try again.
            return null;
        }
    }
}

Webview wv = new WebView(this);
wv.setWebViewClient(wvc);

Если ваша минимальная цель API - уровень 21, вы можете использовать новый shouldInterceptRequest, который дает дополнительную информацию о запросе (например, заголовки), а не только URL.

Ответ 3

Как уже упоминалось ранее, вы можете сделать это:

 WebView  host = (WebView)this.findViewById(R.id.webView);
 String url = "<yoururladdress>";

 Map <String, String> extraHeaders = new HashMap<String, String>();
 extraHeaders.put("Authorization","Bearer"); 
 host.loadUrl(url,extraHeaders);

Я тестировал это и с помощью MVC-контроллера, что я расширил атрибут авторизации, чтобы проверить заголовок, и заголовок есть.

Ответ 4

Возможно, мой ответ довольно поздний, но он охватывает уровень API ниже и выше.

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

Поэтому нам нужно переопределить метод invInterceptRequest, который вызывается в обоих случаях: 1. для API до уровня 21; 2. для уровня API 21 +

    webView.setWebViewClient(new WebViewClient() {

        // Handle API until level 21
        @SuppressWarnings("deprecation")
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

            return getNewResponse(url);
        }

        // Handle API 21+
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

            String url = request.getUrl().toString();

            return getNewResponse(url);
        }

        private WebResourceResponse getNewResponse(String url) {

            try {
                OkHttpClient httpClient = new OkHttpClient();

                Request request = new Request.Builder()
                        .url(url.trim())
                        .addHeader("Authorization", "YOU_AUTH_KEY") // Example header
                        .addHeader("api-key", "YOUR_API_KEY") // Example header
                        .build();

                Response response = httpClient.newCall(request).execute();

                return new WebResourceResponse(
                        null,
                        response.header("content-encoding", "utf-8"),
                        response.body().byteStream()
                );

            } catch (Exception e) {
                return null;
            }

        }
   });

Если тип ответа должен быть обработан, вы можете изменить

        return new WebResourceResponse(
                null, // <- Change here
                response.header("content-encoding", "utf-8"),
                response.body().byteStream()
        );

к

        return new WebResourceResponse(
                getMimeType(url), // <- Change here
                response.header("content-encoding", "utf-8"),
                response.body().byteStream()
        );

и добавьте метод

        private String getMimeType(String url) {
            String type = null;
            String extension = MimeTypeMap.getFileExtensionFromUrl(url);

            if (extension != null) {

                switch (extension) {
                    case "js":
                        return "text/javascript";
                    case "woff":
                        return "application/font-woff";
                    case "woff2":
                        return "application/font-woff2";
                    case "ttf":
                        return "application/x-font-ttf";
                    case "eot":
                        return "application/vnd.ms-fontobject";
                    case "svg":
                        return "image/svg+xml";
                }

                type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            }

            return type;
        }

Ответ 5

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

Доступ к заголовкам, предоставляемым Google, отсутствует. Они находятся в вызове JNI, глубоко в источнике WebView.

Ответ 6

Это работает для меня:

  • Сначала вам нужно создать метод, который будет возвращать ваши заголовки, которые вы хотите добавить к запросу:

    private Map<String, String> getCustomHeaders()
    {
        Map<String, String> headers = new HashMap<>();
        headers.put("YOURHEADER", "VALUE");
        return headers;
    }
    
  • Во-вторых, вам нужно создать WebViewClient:

    private WebViewClient getWebViewClient()
    {
    
        return new WebViewClient()
        {
    
        @Override
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
        {
            view.loadUrl(request.getUrl().toString(), getCustomHeaders());
            return true;
        }
    
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            view.loadUrl(url, getCustomHeaders());
            return true;
        }
    };
    }
    
  • Добавить WebViewClient в WebView:

    webView.setWebViewClient(getWebViewClient());
    

Надеюсь, что это поможет.

Ответ 7

Это сработало для меня. Создайте WebViewClient, как показано ниже, и установите веб-клиент в свой веб-просмотр. Мне пришлось использовать webview.loadDataWithBaseURL, поскольку мои URL-адреса (в моем содержании) не имели baseurl, а только относительные URL-адреса. Вы правильно получите URL-адрес только тогда, когда будет установлен базовый набор с использованием loadDataWithBaseURL.

public WebViewClient getWebViewClientWithCustomHeader(){
    return new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            try {
                OkHttpClient httpClient = new OkHttpClient();
                com.squareup.okhttp.Request request = new com.squareup.okhttp.Request.Builder()
                        .url(url.trim())
                        .addHeader("<your-custom-header-name>", "<your-custom-header-value>")
                        .build();
                com.squareup.okhttp.Response response = httpClient.newCall(request).execute();

                return new WebResourceResponse(
                        response.header("content-type", response.body().contentType().type()), // You can set something other as default content-type
                        response.header("content-encoding", "utf-8"),  // Again, you can set another encoding as default
                        response.body().byteStream()
                );
            } catch (ClientProtocolException e) {
                //return null to tell WebView we failed to fetch it WebView should try again.
                return null;
            } catch (IOException e) {
                //return null to tell WebView we failed to fetch it WebView should try again.
                return null;
            }
        }
    };

}

Ответ 8

Вы можете использовать это:

@Override

 public boolean shouldOverrideUrlLoading(WebView view, String url) {

                // Here put your code
                Map<String, String> map = new HashMap<String, String>();
                map.put("Content-Type","application/json");
                view.loadUrl(url, map);
                return false;

            }

Ответ 9

Используйте это:

webView.getSettings().setUserAgentString("User-Agent");