Ray*_*Ray 85 java android webkit android-webview
我需要为来自WebView的每个请求添加自定义标头.我知道loadURL有参数extraHeaders,但这些只适用于初始请求.所有后续请求都不包含标头.我查看了所有覆盖内容WebViewClient,但没有任何内容允许向资源请求添加标头 - onLoadResource(WebView view, String url).任何帮助都会很精彩.
谢谢,雷
pec*_*eps 72
尝试
loadUrl(String url, Map<String, String> extraHeaders)
Run Code Online (Sandbox Code Playgroud)
要将标头添加到资源加载请求,请创建自定义WebViewClient并覆盖:
API 24+:
WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
or
WebResourceResponse shouldInterceptRequest(WebView view, String url)
Run Code Online (Sandbox Code Playgroud)
Mar*_*cny 33
您需要使用WebViewClient.shouldInterceptRequest拦截每个请求
每次拦截时,您需要获取网址,自己发出此请求,然后返回内容流:
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);
Run Code Online (Sandbox Code Playgroud)
如果您的最低API目标是21级,则可以使用新的shouldInterceptRequest,它会为您提供其他请求信息(例如标题),而不仅仅是URL.
Ser*_*nko 25
也许我的反应很晚,但它涵盖了API 以下和21级以上.
要添加标头,我们应该拦截每个请求并使用所需的标头创建新的请求.
因此我们需要覆盖在两种情况下调用的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;
}
}
});
Run Code Online (Sandbox Code Playgroud)
如果应该处理响应类型,您可以更改
return new WebResourceResponse(
null, // <- Change here
response.header("content-encoding", "utf-8"),
response.body().byteStream()
);
Run Code Online (Sandbox Code Playgroud)
至
return new WebResourceResponse(
getMimeType(url), // <- Change here
response.header("content-encoding", "utf-8"),
response.body().byteStream()
);
Run Code Online (Sandbox Code Playgroud)
并添加方法
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;
}
Run Code Online (Sandbox Code Playgroud)
lee*_*oya 20
如前所述,您可以这样做:
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);
Run Code Online (Sandbox Code Playgroud)
我测试了这个,并使用MVC控制器,我扩展了授权属性以检查标头,标头就在那里.
这对我有用:
首先,您需要创建方法,该方法将返回您要添加到请求的标头:
private Map<String, String> getCustomHeaders()
{
Map<String, String> headers = new HashMap<>();
headers.put("YOURHEADER", "VALUE");
return headers;
}
Run Code Online (Sandbox Code Playgroud)其次,您需要创建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;
}
};
}
Run Code Online (Sandbox Code Playgroud)将WebViewClient添加到WebView:
webView.setWebViewClient(getWebViewClient());
Run Code Online (Sandbox Code Playgroud)希望这可以帮助.
这是使用 HttpUrlConnection 的实现:
class CustomWebviewClient : WebViewClient() {
private val charsetPattern = Pattern.compile(".*?charset=(.*?)(;.*)?$")
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
try {
val connection: HttpURLConnection = URL(request.url.toString()).openConnection() as HttpURLConnection
connection.requestMethod = request.method
for ((key, value) in request.requestHeaders) {
connection.addRequestProperty(key, value)
}
connection.addRequestProperty("custom header key", "custom header value")
var contentType: String? = connection.contentType
var charset: String? = null
if (contentType != null) {
// some content types may include charset => strip; e. g. "application/json; charset=utf-8"
val contentTypeTokenizer = StringTokenizer(contentType, ";")
val tokenizedContentType = contentTypeTokenizer.nextToken()
var capturedCharset: String? = connection.contentEncoding
if (capturedCharset == null) {
val charsetMatcher = charsetPattern.matcher(contentType)
if (charsetMatcher.find() && charsetMatcher.groupCount() > 0) {
capturedCharset = charsetMatcher.group(1)
}
}
if (capturedCharset != null && !capturedCharset.isEmpty()) {
charset = capturedCharset
}
contentType = tokenizedContentType
}
val status = connection.responseCode
var inputStream = if (status == HttpURLConnection.HTTP_OK) {
connection.inputStream
} else {
// error stream can sometimes be null even if status is different from HTTP_OK
// (e. g. in case of 404)
connection.errorStream ?: connection.inputStream
}
val headers = connection.headerFields
val contentEncodings = headers.get("Content-Encoding")
if (contentEncodings != null) {
for (header in contentEncodings) {
if (header.equals("gzip", true)) {
inputStream = GZIPInputStream(inputStream)
break
}
}
}
return WebResourceResponse(contentType, charset, status, connection.responseMessage, convertConnectionResponseToSingleValueMap(connection.headerFields), inputStream)
} catch (e: Exception) {
e.printStackTrace()
}
return super.shouldInterceptRequest(view, request)
}
private fun convertConnectionResponseToSingleValueMap(headerFields: Map<String, List<String>>): Map<String, String> {
val headers = HashMap<String, String>()
for ((key, value) in headerFields) {
when {
value.size == 1 -> headers[key] = value[0]
value.isEmpty() -> headers[key] = ""
else -> {
val builder = StringBuilder(value[0])
val separator = "; "
for (i in 1 until value.size) {
builder.append(separator)
builder.append(value[i])
}
headers[key] = builder.toString()
}
}
}
return headers
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不适用于 POST 请求,因为 WebResourceRequest 不提供 POST 数据。有一个请求数据 - WebViewClient 库,它使用 JavaScript 注入解决方法来拦截 POST 数据。
| 归档时间: |
|
| 查看次数: |
100302 次 |
| 最近记录: |