Добавление пользовательских заголовков в запросы ресурсов 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");