在WebView中加载网页后,有没有办法在Activity中查看http响应标头?看起来这应该是可能的,但我找不到任何暴露标题的方法。
答案 0 :(得分:32)
WebView
和WebViewClient
都没有提供方法,但是,您可以尝试手动实现。你可以这样做:
private WebView webview;
public void onCreate(Bundle icicle){
// bla bla bla
// here you initialize your webview
webview = new WebView(this);
webview.setWebViewClient(new YourWebClient());
}
// this will be the webclient that will manage the webview
private class YourWebClient extends WebViewClient{
// you want to catch when an URL is going to be loaded
public boolean shouldOverrideUrlLoading (WebView view, String urlConection){
// here you will use the url to access the headers.
// in this case, the Content-Length one
URL url;
URLConnection conexion;
try {
url = new URL(urlConection);
conexion = url.openConnection();
conexion.setConnectTimeout(3000);
conexion.connect();
// get the size of the file which is in the header of the request
int size = conexion.getContentLength();
}
// and here, if you want, you can load the page normally
String htmlContent = "";
HttpGet httpGet = new HttpGet(urlConection);
// this receives the response
HttpResponse response;
try {
response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
// la conexion fue establecida, obtener el contenido
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = entity.getContent();
htmlContent = convertToString(inputStream);
}
}
} catch (Exception e) {}
webview.loadData(htmlContent, "text/html", "utf-8");
return true;
}
public String convertToString(InputStream inputStream){
StringBuffer string = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
try {
while ((line = reader.readLine()) != null) {
string.append(linea + "\n");
}
} catch (IOException e) {}
return string.toString();
}
}
我现在无法测试它,但这基本上就是你可以做的事情(尽管它非常疯狂:)。
答案 1 :(得分:2)
受到Cristian answer的启发我需要拦截webview正在进行的AJAX调用,我需要拦截响应标头以获取一些信息(电子商务应用中的购物车项目数),这是我需要的在应用程序中利用。由于应用程序正在使用okhttp,我最终做到了这一点它正在运行:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
Log.i(TAG,"shouldInterceptRequest path:"+request.getUrl().getPath());
WebResourceResponse returnResponse = null;
if (request.getUrl().getPath().startsWith("/cart")) { // only interested in /cart requests
returnResponse = super.shouldInterceptRequest(view, request);
Log.i(TAG,"cart AJAX call - doing okRequest");
Request okRequest = new Request.Builder()
.url(request.getUrl().toString())
.post(null)
.build();
try {
Response okResponse = app.getOkHttpClient().newCall(okRequest).execute();
if (okResponse!=null) {
int statusCode = okResponse.code();
String encoding = "UTF-8";
String mimeType = "application/json";
String reasonPhrase = "OK";
Map<String,String> responseHeaders = new HashMap<String,String>();
if (okResponse.headers()!=null) {
if (okResponse.headers().size()>0) {
for (int i = 0; i < okResponse.headers().size(); i++) {
String key = okResponse.headers().name(i);
String value = okResponse.headers().value(i);
responseHeaders.put(key, value);
if (key.toLowerCase().contains("x-cart-itemcount")) {
Log.i(TAG,"setting cart item count");
app.setCartItemsCount(Integer.parseInt(value));
}
}
}
}
InputStream data = new ByteArrayInputStream(okResponse.body().string().getBytes(StandardCharsets.UTF_8));
Log.i(TAG, "okResponse code:" + okResponse.code());
returnResponse = new WebResourceResponse(mimeType,encoding,statusCode,reasonPhrase,responseHeaders,data);
} else {
Log.w(TAG,"okResponse fail");
}
} catch (IOException e) {
e.printStackTrace();
}
}
return returnResponse;
}
我希望这可能对其他人有所帮助,如果有人提出改进建议,我将不胜感激。不幸的是它只与LOLLIPOP和更高版本兼容,因为从这个版本你可以使用WebResourceRequest访问/返回标题,这是我的情况所需要的。
答案 2 :(得分:1)
您应该能够通过跳过loadUrl并使用Java的HttpURLConnection编写自己的loadPage来控制所有标头。然后查看标题,做你的事情,并使用webview的loadData来显示响应。
答案 3 :(得分:0)
如果您至少要瞄准Kit-Kat,则有另一种解决方案,即使这不会在Activity中显示标题,而在Chrome中显示标题。您只需遵循简短的guide来了解如何远程调试Webview。
首先要注意的2个关键点是
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
然后在计算机的Chrome标签中打开chrome://inspect
。通过USB将手机连接到计算机后,您将在可调试设备列表中看到应用的WebView
答案 4 :(得分:-1)
您可以使用OkHttp:
private fun handleRequestViaOkHttp(url: String) {
var httpClient = OkHttpClient()
thread {
try {
val request = Request.Builder().url(url).build()
print("Request: $request")
val response = httpClient.newCall(request).execute()
println("Response: " + response.headers().toString())
} catch (e: Exception) {}
}
}
您应该在此方法内调用它:
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
handleRequestViaOkHttp(webViewUrl.value.toString())
return super.shouldInterceptRequest(view, request)
}
答案 5 :(得分:-3)
由于接受的答案只适用于HttpGet,这是我目前正在使用的一个技巧(此时它似乎有效)
在onPageFinished处理程序中,如果出现错误,页面的标题将类似于“ERROR_NUM - ERROR_DESCRIPTION”,如“500 - Internal Server Error”,所以我所做的就是从函数中的webview获取标题,然后检查标题。
view.getTitle()