Android WebViewClient url redirection (Android URL loading system)

余生长醉 提交于 2019-12-06 07:28:04

问题


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?


回答1:


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).




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!