安卓 WebViewClient URL 重定向 (安卓 URL 加载系统)

5
我试图使用ShouldInterceptRequest拦截Webview请求,内部使用HttpUrlConnection从服务器获取数据,并设置其跟随重定向,这对于Webview客户端来说是透明的。这意味着当我返回WebResponseResource(“”,“”,data_inputstream)时,Webview可能不知道目标主机已更改。我该如何告诉Webview发生了这种情况?
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);

            }
        }

如果我请求“google.com”,它应该被重定向到“google.co.uk”,但是 webview 不知道重定向,如果带有“co.uk”的 css 文件链接是“/render/something.css”,那么 webview 仍然会去 "http://www.google.com/render/something.css" 找到应该是 "http://www.google.co.uk/render/something.css" 的 css 文件。
有人可以帮我吗?
3个回答

1

某些元数据(如url、headers等)无法由WebResourceResponse类指定。这意味着您只能使用shouldInterceptRequest提供不同的数据(更改页面内容),但不能用它来更改正在加载的URL。

在你的情况下,你正在HttpUrlConnection中使用重定向,因此WebView仍然认为它正在加载“http://www.google.com/”(即使内容来自“http://google.co.uk/”)。如果Google的主页没有明确设置基本URL,那么WebView将继续假定基本URL是“http://www.google.com/”(因为它还没有看到重定向)。由于相对资源引用(如<link href="//render/something.css" />)是针对baseURL解析的(在这种情况下,它是“http://www.google.com/”,而不是“http://www.google.co.uk/”),所以你会得到你观察到的结果。
你可以使用HttpUrlConnection来确定要加载的URL是否是重定向,并在这种情况下返回null。但是,我强烈建议不要在一般情况下从shouldInterceptRequest中使用HttpUrlConnection - WebView的网络堆栈更加高效,并且将并行执行获取(而使用shouldInterceptRequest将序列化所有负载在早期版本的WebView中)。

0
关闭HttpClient的setFollowRedirects(false)并让webview重新加载重定向的URL。
虚假代码:
if(response.code == 302){
  webview.load(response.head("location"));
}

-1
您可以为所有 HttpURLConnection 对象全局启用 HTTP 重定向:
HttpURLConnection.setFollowRedirects(true);

然后在shouldInterceptRequest()方法中,您检查连接响应代码:

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

Android框架应该再次调用shouldInterceptRequest(),并使用新的URL作为重定向目标,这时连接响应代码将会是2xx。


1
你需要禁用“followRedirects”而不是启用它(默认情况下它们是启用的)。当启用followRedirects时,你永远不会收到3xx代码。 - Alex Lipov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接