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

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

Спасибо, Рэй

Пытаться

 loadUrl(String url, Map extraHeaders) 

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

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

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

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

 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 , вы можете использовать новый mustInterceptRequest, который дает вам дополнительную информацию о запросе (например, заголовки), а не только URL-адрес.

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

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

Поэтому нам нужно переопределить метод 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; } 

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

  WebView host = (WebView)this.findViewById(R.id.webView); String url = ""; Map  extraHeaders = new HashMap(); extraHeaders.put("Authorization","Bearer"); host.loadUrl(url,extraHeaders); 

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

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

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

     private Map getCustomHeaders() { Map headers = new HashMap<>(); headers.put("YOURHEADER", "VALUE"); return headers; } 
  2. Во-вторых, вам нужно создать 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; } }; } 
  3. Добавьте WebViewClient в WebView:

     webView.setWebViewClient(getWebViewClient()); 

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

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

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

Это сработало для меня. Создайте WebViewClient, как показано ниже, и установите веб-клиент в свой веб-просмотр. Мне пришлось использовать webview.loadDataWithBaseURL, поскольку мои URL-адреса (в моем содержании) не имели baseurl, а только относительные URL-адреса. Вы правильно получите URL-адрес, только если есть набор baseurl, использующий 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("", "") .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; } } }; } 

Я столкнулся с той же проблемой и решил.

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

 WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) 

Этот метод должен вызывать webView.loadUrl, возвращая «пустой» WebResourceResponse.

Что-то вроде этого:

 @Override public boolean shouldInterceptRequest(WebView view, WebResourceRequest request) { // Check for "recursive request" (are yor header set?) if (request.getRequestHeaders().containsKey("Your Header")) return null; // Add here your headers (could be good to import original request header here!!!) Map customHeaders = new HashMap(); customHeaders.put("Your Header","Your Header Value"); view.loadUrl(url, customHeaders); return new WebResourceResponse("", "", null); } 

Страница: MainActivity.java

импортировать android.webkit.WebView;

открытый class MainActivity расширяет AppCompatActivity {

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WebView WebViw = (WebView) findViewById(R.id.webView1); WebViw.getSettings().setJavaScriptEnabled(true); WebViw.getSettings().setUserAgentString("User-Agent"); WebViw.loadUrl("http://www.educationlife-online.com/"); } 

}

таким образом, это успех.

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

 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // Here put your code Map map = new HashMap(); map.put("Content-Type","application/json"); view.loadUrl(url, map); return false; } 

Использовать это:

 webView.getSettings().setUserAgentString("User-Agent"); 
  • AlertDialog изнутри BroadcastReceiver ?? Это можно сделать?
  • Ошибка: java: javacTask: исходный выпуск 8 требует целевого релиза 1.8
  • Не удалось выполнить com.google.android.gms play-services-auth: 11.4.0
  • Получить объект JSON из ответа HTTP
  • Почему файл Java должен иметь то же имя, что и его открытый class?
  • Как разбирать JSON Array (не Json Object) в Android
  • Что такое синтаксис?
  • Eclipse: JVM завершена. Код выхода = 2
  • eclipse с Android sdk, ERROR: пространство кучи Java
  • Перемещение изображения по спирали в java
  • Точка входа для приложений Java: main (), init () или run ()?
  • Давайте будем гением компьютера.