添加自定义标题到WebView资源请求 – android

我需要为来自WebView的每个请求添加自定义标头。 我知道loadURLextraHeaders的参数,但这些只适用于初始请求。 所有后续请求不包含标题。 我已经看了WebViewClient中的所有覆盖,但没有任何东西允许向资源请求添加标头 – onLoadResource(WebView view, String url) 。 任何帮助将是美好的。

谢谢,雷

尝试

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

这只适用于API8 +。

您将需要使用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级 ,那么您可以使用新的shouldInterceptRequest ,它会为您提供其他请求信息(如标题)而不仅仅是URL。

如前所述,你可以这样做:

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

我testing了这一点,并与一个MVC控制器,我扩展了授权属性来检查标题和标题在那里。

也许我的反应比较晚,但是它覆盖了21级以下的 API。

要添加标题,我们应该拦截每个请求,创build一个新的标题。

因此,我们需要重写在两种情况下调用的shouldInterceptRequest方法: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; } } }); 

如果响应types应该被处理,你可以改变

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

您应该能够通过跳过loadUrl并使用Java的HttpURLConnection编写自己的loadPage来控制所有的头文件。 然后使用webview的loadData来显示响应。

无法访问Google提供的标题。 它们在WebView源代码中处于JNI调用。

这适用于我:

  1. 首先你需要创build方法,这将返回你想要添加的请求头:

     private Map<String, String> getCustomHeaders() { Map<String, String> headers = new HashMap<>(); headers.put("YOURHEADER", "VALUE"); return headers; } 
  2. 其次你需要创buildWebViewClient:

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

希望这可以帮助。

这对我有效。 像下面这样创buildWebViewClient并将webclient设置为您的webview。 我不得不使用webview.loadDataWithBaseURL作为我的网站(在我的内容)没有baseurl,但只有相对的url。 只有在使用loadDataWithBaseURL设置了baseurl时,才能正确获取url。

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

你可以使用这个:

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

用这个:

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