Add custom headers to WebView resource requests - android
Solution 1:
Try
loadUrl(String url, Map<String, String> extraHeaders)
For adding headers to resources loading requests, make custom WebViewClient and override:
API 24+:
WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
or
WebResourceResponse shouldInterceptRequest(WebView view, String url)
Solution 2:
You will need to intercept each request using WebViewClient.shouldInterceptRequest
With each interception, you will need to take the url, make this request yourself, and return the content 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);
If your minimum API target is level 21, you can use the new shouldInterceptRequest which gives you additional request information (such as headers) instead of just the URL.
Solution 3:
Maybe my response quite late, but it covers API below and above 21 level.
To add headers we should intercept every request and create new one with required headers.
So we need to override shouldInterceptRequest method called in both cases: 1. for API until level 21; 2. for API level 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;
}
}
});
If response type should be processed you could change
return new WebResourceResponse(
null, // <- Change here
response.header("content-encoding", "utf-8"),
response.body().byteStream()
);
to
return new WebResourceResponse(
getMimeType(url), // <- Change here
response.header("content-encoding", "utf-8"),
response.body().byteStream()
);
and add method
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;
}
Solution 4:
As mentioned before, you can do this:
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);
I tested this and on with a MVC Controller that I extended the Authorize Attribute to inspect the header and the header is there.