I was trying intercept webview request using: ShouldInterceptRequest
, inside it I used HttpUrlConnection
to fetch data from server, I set it to follow the redirection, which is transparent to webviewclient. This means when I return WebResponseResource("", "", data_inputstream), webview maynot know the target host was changed. How can I tell the webview this happened?
ourBrowser.setWebViewClient(new WebViewClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view,
String url) {
..... //some code omitted here
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) newUrl.openConnection();
conn.setFollowRedirects(true);
} catch (IOException e) {
e.printStackTrace();
}
..... //
InputStream is = null;
try {
is = conn.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
return new WebResourceResponse(mimeType, encoding, is);
}
}
If I request "google.com", it should be redirected to "google.co.uk", but webview didnt know the redirection, if the link of css file attaching with "co.uk" is "/render/something.css", the webview still go to "http://www.google.com/render/something.css" to find the css file which should be "http://www.google.co.uk/render/something.css".
Anyone can help me?
Certain metadata (url, headers, etc..) can't be specified by the WebResourceResponse
class. That means that you can only use shouldInterceptRequest
to supply different data (change the page's content) but you can't use it to change the URL it's being loaded at.
In your case you're consuming the redirect within the HttpUrlConnection
, so the WebView is still thinking that it's loading "http://www.google.com/" (even if the content is coming from "http://google.co.uk/"). If Google's home page doesn't explicitly set a base URL the WebView will continue to assume the base URL is "http://www.google.com/" (since it hasn't seen the redirect). Since relative resource references (like <link href="//render/something.css" />
) are resolved against the baseURL (which in this case is "http://www.google.com/" and not "http://www.google.co.uk/") you get the result you observed.
What you could do is use HttpUrlConnection
to figure out whether the URL you're going to load is a redirect and return null
in that case. However I would strongly advise against using HttpUrlConnection
from shouldInterceptRequest
in general - the WebView's network stack is much more efficient and will perform fetches in parallel (whereas using shouldInterceptRequest
will serialize all of the loads in pre-KK WebViews).
You can enable HTTP redirects globally for all the HttpURLConnection objects:
HttpURLConnection.setFollowRedirects(true);
then in the shouldInterceptRequest() method you check for the connection response code:
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
...
int respCode = conn.getResponseCode();
if( respCode >= 300 && respCode < 400 ) {
// redirect
return null;
} else if( respCode >= 200 && respCode < 300 ) {
// normal processing
...
}
The Android framework should call shouldInterceptRequest() again with the new URL which is the redirection target, and this time the connection response code will be 2xx.
来源:https://stackoverflow.com/questions/18237451/android-webviewclient-url-redirection-android-url-loading-system