Android正确拦截WebView请求

时间:2017-01-23 12:59:43

标签: android cookies webview

我目前在网页浏览中拦截请求的代码是

 @Override
public WebResourceResponse shouldInterceptRequest(WebView view,
    String url) {
    String ext = MimeTypeMap.getFileExtensionFromUrl(url);
    String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
    if (mime == null) {
        return super.shouldInterceptRequest(view, url);
    } else {
        HttpURLConnection conn = (HttpURLConnection) new URL(
                                                 url).openConnection();
        conn.setRequestProperty("User-Agent", userAgent);
        return new WebResourceResponse(mime, "UTF-8",
                                                 conn.getInputStream());
    }
}

我从中得到了这段代码 The best way to intercept a WebView request in Android

但是,每当我尝试执行身份验证时,假设我在我的webview中加载facebook。

mWebView.loadUrl("https://www.facebook.com/");

什么都没发生,我注意到的是,请求标头是不完整的,也是响应。此外,源中没有cookie。 (当我通过Chrome远程调试webview时,我看到了这一点。)

如果我错了,请纠正我,但我认为不完整的标题和丢失的Cookie是导致登录请求失败的原因。

有没有办法可以修改请求并设置其标题?对于回应,我也应该这样做吗?最后,我将如何获得cookie。

1 个答案:

答案 0 :(得分:1)

这个问题在6个月内没有得到解答,所以我不知道你是否还需要这个问题,但也许其他人有类似的问题。

  

请求标头不完整

使用HttpURLConnection时,您将负责设置您可能需要的任何请求标头,但它就像设置您已执行的用户代理一样简单:conn.setRequestHeader(header, value)或者您需要添加而不是覆盖标题值:conn.addRequestHeader(header, value)

或者,您可以使用okhttp,一个HTTP客户端,它应该添加标头的默认值,这是通常需要的。

  

来源

中没有Cookie

当拦截请求时,您还将负责处理cookie。您可以通过解析响应中的标题来手动存储cookie,例如

    public WebResourceResponse shouldInterceptRequest(WebView view,
       String url) { 
       // do your stuff
       conn.connect(); // required to tell that the connection should be established
       String cookie = getCookieFromConnection(conn);
       // do more stuff and return WebResourceResponse
    }

    /**
     * iterates all headers, and finds "cookie" headers 
     * (there could be more than one)
     * @return cookie (concatenated value of all the found cookies)
     * or null if no cookie has been found
     */
    private String getCookieFromConnection(HttpURLConnection connection) {
       String cookie = "";
       Map<String, List<String>> header = connection.getHeaderFields();
       List<String> cookies = header.get(COOKIE_HEADER);
       if (cookies != null) {
           for (String c : cookies) {
               if (c != null) cookie += c + ";";
           }
       }
       if (cookie.isEmpty()) return null;
       return cookie;
}

或者您可以使用CookieManager,它可以为您处理所有事情:

    cookieManager = new CookieManager();
    CookieHandler.setDefault(cookieManager); 
    cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);

使用okhttp时,您可能还需要处理Cookie,但您可以再次使用上述CookieManager。有关详细信息,请参阅此文档,或stackoverflow question

  

如果我错了,请纠正我,但我认为不完整的标题和丢失的Cookie是导致登录请求失败的原因。

当拦截WebView中的请求时还有另一个问题:它以某种方式停止加载和评估javascript。我在网上发现了这个blog by Artem Zinnatullin,他描述了这种行为,并且我遇到了同样的行为。

如果有人能解决这个问题,我会非常高兴。