【问题标题】:Maintain session between HttpUrlConnection Calls (Native/Webview)保持 HttpUrlConnection 调用之间的会话(本机/Webview)
【发布时间】:2016-02-07 06:30:35
【问题描述】:

让我从我渴望开始:

我想制作一个part native and part webviews 的应用程序。

问题 - 在本机部件和 web 视图部件之间保持会话。

我的处理方法

我打算实现一个本机登录,其中我向用户展示了两个 EditTextbox 和一个按钮,用户输入凭据并将它们作为 JSON 发布到服务器。

服务器响应成功或错误。根据 Success 标志,我读取此连接的标头值并提取 SessionCookie:

switch (responseCode) {
                case 200:

                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    String inputLine;
                    response = new StringBuffer();
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();

                   //IF SUCCESS

                    Map<String, List<String>> map = conn.getHeaderFields();

                    for (Map.Entry<String, List<String>> entry : map.entrySet()) {
                        System.out.println("Key : " + entry.getKey() + " ,Value : " + entry.getValue());
                    }

                    SSID = map.get("Set-Cookie").toString();
                    SSID = SSID.substring(1,SSID.length()-1);
                    return response.toString();
            }

如下所示:

Set-Cookie ,Value : [PHPSESSID=e407ef64abb71b1ea2b8e4b30db76cf0; path=/, ci_session=a%3A0%3A%7B%7D; expires=Thu, 06-Nov-2014 16:54:57 GMT; Max-Age=-31500000; path=/, ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D5f4013e4a2edd2eb891ec8a2b8e8716e; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/]

警告:在上面expires=Thu, 06-Nov-2014 16:54:57 GMT

现在我想去一个 webview 并将这个 cookie 添加到标题中,我正在这样做:

Map<String, String> abc = new HashMap<String, String>();
            abc.put("Cookie", UniversalHttpUrlConnection.SSID);
            webView.loadUrl("https://someUrl/show_all", abc);

但上述不起作用

我尝试了一种不同的方法,只是从上面的 webview URL 中读取HTML

 public static String doHttpUrlConnectionAction(String desiredUrl, String headerValue)
            throws Exception {
        URL url = null;
        BufferedReader reader = null;
        StringBuilder stringBuilder;

        try {

            url = new URL(desiredUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("Cookie", headerValue);

            connection.setRequestMethod("GET");

            connection.setDoOutput(true);


            connection.setReadTimeout(15 * 1000);
            connection.connect();


            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            stringBuilder = new StringBuilder();

            String line = null;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line + "\n");
            }
            return stringBuilder.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {

            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }

    }

我得到的 HTML 是登录页面的 HTML,它本质上是一个重定向 - 因为服务器无法识别会话并重定向我。我在这里想念什么?如何继续会话?

编辑 - 进一步调试:

使用已弃用的:

HttpClient httpClient = new DefaultHttpClient(); //

我得到了这些标题:

Key : Date ,Value : Sat, 07 Nov 2015 08:22:28 GMT
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Server ,Value : Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : PHPSESSID=f27454f855fc5d5b2efa478537725992; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Expires ,Value : Thu, 19 Nov 1981 08:52:00 GMT
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Cache-Control ,Value : no-store, no-cache, must-revalidate, post-check=0, pre-check=0
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Pragma ,Value : no-cache
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A0%3A%7B%7D; expires=Fri, 07-Nov-2014 18:22:28 GMT; Max-Age=-31500000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D58938a4e97b08c01faa7fec0025bdc49; expires=Mon, 06-Nov-2017 08:22:28 GMT; Max-Age=63072000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3B%7D30e2cc6561b3fb9659c7809d0c82946d; expires=Mon, 06-Nov-2017 08:22:28 GMT; Max-Age=63072000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3B%7D30e2cc6561b3fb9659c7809d0c82946d; expires=Mon, 06-Nov-2017 08:22:28 GMT; Max-Age=63072000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Vary ,Value : Accept-Encoding
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Content-Length ,Value : 95
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Connection ,Value : close
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Content-Type ,Value : text/html

一开始还有一个警告

Invalid cookie header: "Set-Cookie: ci_session=a%3A0%3A%7B%7D; expires=Fri, 07-Nov-2014 18:22:28 GMT; Max-Age=-31500000; path=/". Negative max-age attribute: -31500000

观察 Set-Cookie 来了 4 次,第一次导致异常。

现在使用 HttpUrlConnection:

HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();

以下是我得到的标题:

 Key : null ,Value : [HTTP/1.1 200 OK]
11-07 13:52:27.646 5264-5291/projects.test.com.webviewtest I/System.out: Key : Cache-Control ,Value : [no-store, no-cache, must-revalidate, post-check=0, pre-check=0]
11-07 13:52:27.646 5264-5291/projects.test.com.webviewtest I/System.out: Key : Connection ,Value : [close]
11-07 13:52:27.646 5264-5291/projects.test.com.webviewtest I/System.out: Key : Content-Type ,Value : [text/html]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Date ,Value : [Sat, 07 Nov 2015 08:22:29 GMT]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Expires ,Value : [Thu, 19 Nov 1981 08:52:00 GMT]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Pragma ,Value : [no-cache]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Server ,Value : [Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4]
11-07 13:52:27.650 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : [PHPSESSID=9d98c8d97660664e550f19913783c089; path=/, ci_session=a%3A0%3A%7B%7D; expires=Fri, 07-Nov-2014 18:22:29 GMT; Max-Age=-31500000; path=/, ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%228cf5e634854030668573ec1f0dc9c6d9%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884549%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D9e233ffe356e965178da38e538fd8b31; expires=Mon, 06-Nov-2017 08:22:29 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%228cf5e634854030668573ec1f0dc9c6d9%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884549%3B%7D53b1ee5e2e625d24d33a153a50881093; expires=Mon, 06-Nov-2017 08:22:29 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%228cf5e634854030668573ec1f0dc9c6d9%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884549%3B%7D53b1ee5e2e625d24d33a153a50881093; expires=Mon, 06-Nov-2017 08:22:29 GMT; Max-Age=63072000; path=/]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : Vary ,Value : [Accept-Encoding]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : X-Android-Received-Millis ,Value : [1446884547643]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : X-Android-Response-Source ,Value : [NETWORK 200]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : X-Android-Sent-Millis ,Value : [1446884547076]

观察: Set-Cookie 是打包在一起的,四个实例。

当我手动在Advanced Rest Client 中尝试此操作时,一切正常。我得到了所需的 HTML 页面 - 已通过身份验证。

观察: Advanced Rest Client App 只有当我在同一个浏览器中登录网站时才会给出正确的结果。所以基本上cookies被覆盖了。

观察

我厌倦了尝试从 HttpUrlConnection 获取会话 cookie,我所做的更改是加载一个 webview 并在其中登录。

其次,我设置了一个按钮来触发我的 HttpUrlConnection - 并尝试访问需要身份验证的页面。

在这个 HttpUrlConnection 里面我做了这样的事情:

 CookieManager cookieManager = CookieManager.getInstance();
            String cookie = cookieManager.getCookie(new URL("https://urlinQuestion.com").getHost());
            System.out.println("Cookie from cookie store" + cookie);
            connection.setRequestProperty("Cookie", cookie);

所以我将在 webView 中获得的 cookie 传递给 HttpUrlCONnection。有用。现在我觉得为了颠倒事件的顺序(因为我想要 cookie 来自 UrlConnection - 将它们传递给 webview)我将不得不更新 cookie 管理器。 (新航程从这里开始)

为了记录起见,我在下面添加了两个 cookie: 第一个不起作用,第二个我从 webview 方式获得并且可以工作,但我发现语义上没有区别:

PHPSESSID=a3d2367f8a5a3221e9bad1a91a34fd55; ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%221381c152699fb61d04663c9b854ecdd7%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A14%3A%22182.59.245.196%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1447140920%3B%7Ddd2c014724b9ca061b50774f1fea235d


PHPSESSID=348345a2bf9f9733037915fd36a4ad6c; 
ci_session=a%3A4%3A%7Bs%3A10%3A%22
session_id%22%3Bs%3A32%3A%2209304f814a6ed6ad726dabca74b94182%22%3Bs%3A10%3A%22
ip_address%22%3Bs%3A14%3A%22182.59.202.107%22%3Bs%3A10%3A%22
user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22
last_activity%22%3Bi%3A1447127988%3B%7D18055bfdb2d59618a324aff37a58871d

使用this工具阅读以上内容

【问题讨论】:

    标签: java php android session httpurlconnection


    【解决方案1】:

    我最接近的方法是使用 webview 作为登录名。然后你可以在 HttpUrlConnection 中继续你的会话,使用从 webview 获取的 cookie。 cookie 可按如下方式使用:

    HttpURLConnection urlConnection = null;
    try {
        urlConnection = (HttpURLConnection) url.openConnection();
    
        // Fetch and set cookies in requests
        CookieManager cookieManager = CookieManager.getInstance();
        String cookie = cookieManager.getCookie(urlConnection.getURL().toString());
        if (cookie != null) {
            urlConnection.setRequestProperty("Cookie", cookie);
        }
        urlConnection.connect();
    
        // Get cookies from responses and save into the cookie manager
        List cookieList = urlConnection.getHeaderFields().get("Set-Cookie");
        if (cookieList != null) {
            for (String cookieTemp : cookieList) {
                cookieManager.setCookie(urlConnection.getURL().toString(), cookieTemp);
            }
        }
    
        InputStream in = new BufferedInputStream (urlConnection.getInputStream());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
    

    【讨论】:

    • 是的,这是我现在能做的最好的事情。虽然是替代品。
    【解决方案2】:

    您应该在请求中发送Cookie 标头,而不是Set-Cookie
    示例请阅读https://www.rfc-editor.org/rfc/rfc6265

    当您的客户端在 HTTP response 标头中收到会话 cookie 时

    Set-Cookie: PHPSESSID=e407ef64abb71b1ea2b8e4b30db76cf0; path=/
    

    它应该将此 cookie 添加到后续 HTTP requests 标头中

    Cookie: PHPSESSID=e407ef64abb71b1ea2b8e4b30db76cf0
    

    编辑:

    原生的PHPSESSID有点混乱,不过使用ci_session cookie的最后一个值应该没问题,例如来自回复

    Set-Cookie ,Value : [PHPSESSID=e407ef64abb71b1ea2b8e4b30db76cf0; path=/, ci_session=a%3A0%3A%7B%7D; expires=Thu, 06-Nov-2014 16:54:57 GMT; Max-Age=-31500000; path=/, ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D5f4013e4a2edd2eb891ec8a2b8e8716e; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/]
    

    将以下标头添加到 webview 请求:

    abc.put("Cookie", "ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3B%7D30e2cc6561b3fb9659c7809d0c82946d");
    

    我建议迭代SSID = map.get("Set-Cookie"),使用/(ci_session=.*?);/ 正则表达式测试每个单独的“Set-Cookie”标头,然后返回最后一个匹配项。

    请注意,您 Web 视图中的 User-Agent 标头应与会话中的 user_agent 匹配。在上面的cookie中是Apache-HttpClient/UNAVAILABLE (java 1.4),看来webview用的是Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 5 Build/LMY48B)

    【讨论】:

    • 我同意,我没有使用字符串“Set-Cookie”,而是使用“Cookie”,但不同之处在于我正在重新发送整个字符串。让我试试你所说的。
    • 不行,我也试过这样:for (String cookie : cookies) { connection.setRequestProperty("Cookie", cookie.split(";", 2)[0]); System.out.println("Cookie" + cookie.split(";", 2)[0]); } 又不行!
    • 啊,是的。我误读了日志。当您收到多个Set-Cokie: name1=value1; path=..; domain=...Set-Cokie: name2=value2; path=..; domain=... 时,将它们作为单个标头Cookie: name1=value1; name2=value2 添加到请求中。
    • @User3 我更仔细地阅读了这个问题,并更新了我的答案。不幸的是,除非您同时控制这两个服务器端应用程序,否则没有好消息。
    • 不是这样,我已经关闭了服务器端的USer代理。
    【解决方案3】:

    java.net.CookieManager 的出色实现。

    我已经实现了自己的想法。它实际上很酷。我创建了 我自己的 java.net.CookieManager 实现,它转发所有 对 WebViews 的 webkit android.webkit.CookieManager 的请求。这 表示不需要同步并且 HttpURLConnection 使用相同的 cookie 存储为 WebView。



    类 WebkitCookieManagerProxy:

    import java.io.IOException;
    import java.net.CookieManager;
    import java.net.CookiePolicy;
    import java.net.CookieStore;
    import java.net.URI;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    public class WebkitCookieManagerProxy extends CookieManager 
    {
        private android.webkit.CookieManager webkitCookieManager;
    
        public WebkitCookieManagerProxy()
        {
            this(null, null);
        }
    
        public WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy)
        {
            super(null, cookiePolicy);
    
            this.webkitCookieManager = android.webkit.CookieManager.getInstance();
        }
    
        @Override
        public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException 
        {
            // make sure our args are valid
            if ((uri == null) || (responseHeaders == null)) return;
    
            // save our url once
            String url = uri.toString();
    
            // go over the headers
            for (String headerKey : responseHeaders.keySet()) 
            {
                // ignore headers which aren't cookie related
                if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;
    
                // process each of the headers
                for (String headerValue : responseHeaders.get(headerKey))
                {
                    this.webkitCookieManager.setCookie(url, headerValue);
                }
            }
        }
    
        @Override
        public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException 
        {
            // make sure our args are valid
            if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");
    
            // save our url once
            String url = uri.toString();
    
            // prepare our response
            Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();
    
            // get the cookie
            String cookie = this.webkitCookieManager.getCookie(url);
    
            // return it
            if (cookie != null) res.put("Cookie", Arrays.asList(cookie));
            return res;
        }
    
        @Override
        public CookieStore getCookieStore() 
        {
            // we don't want anyone to work with this cookie store directly
            throw new UnsupportedOperationException();
        }
    }
    

    并通过在您的应用程序初始化中执行此操作来使用它:

    android.webkit.CookieSyncManager.createInstance(appContext);
    // unrelated, just make sure cookies are generally allowed
    android.webkit.CookieManager.getInstance().setAcceptCookie(true);
    
    // magic starts here
    WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL);
    java.net.CookieHandler.setDefault(coreCookieManager);
    

    参考:Talkol - WebkitCookieManagerProxy

    【讨论】:

    • 这不起作用,我已经阅读了这个答案,然后才发布了一个新问题。
    • 好吧,究竟是什么不起作用?未调用回调? Webview 没有加载?会话未共享?缺少内容?我看到您使用的是 Android 5.1.1,并且带有 cookie 的 Webview 行为发生了很大变化。哪个 API 级别作为最低和目标? mixed-content/cookies
    • 会话未维护。时期!让我们将 5.1.1 视为最小值和最大值!为了添加更多细节,我在 cookie 存储中正确设置了 cookie,并将它们返回到下一个 URlConnection 中。但不知何故,会话失败了。我在下一个 URL 连接中获得了登录 HTML。
    • 让我们在这里根本不考虑 web 视图,让我们考虑两个 URL 连接,一个用于传递用户凭据 - 如果用户进行身份验证,则获取“Set-Cookie”值。在 cookieManager CookieManager.getInstance().setCookie 中添加这些 Cookie,然后启动新的 URL 连接 - 读取 cookie - CookieManager.getInstance().getCookie 并从此处获取原始 html。它坏了 - 让我进入登录页面。
    • 但是,如果我使用 webview 登录,然后为该域获取 cookie,一切正常。本机 HttpUrlConnection 能够持久化会话。
    【解决方案4】:

    尝试将这两行添加到您想要的任何位置。 (也许如果你扩展 Application 类并将它们添加到 onCreate() 方法会更好)

    CookieManager cookieManager = new CookieManager();
    CookieHandler.setDefault(cookieManager);
    

    【讨论】:

    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 2013-07-17
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多