2

在通过 POST 请求发送用户凭据后,我试图从网站获取 cookie,但它似乎在 android 中无法以这种方式工作。¿ 我是在做坏事吗?请帮忙。我在不同的帖子中搜索过这里,但没有有用的答案。

奇怪的是,它在桌面 Java 实现中运行它完美无缺,但它在 Android 平台上崩溃。并且是完全相同的代码,特别是在调用 HttpURLConnection.getHeaderFields() 时,其他成员方法也会发生这种情况。这是一个简单的代码,我不知道为什么它不起作用。

桌面代码:这只是在 main()

HttpURLConnection connection = null;
        OutputStream out = null;
        try {                   
            URL url = new URL("http://www.XXXXXXXX.php");           
            String charset = "UTF-8";       

            String postback = "1";
            String user = "XXXXXXXXX";
            String password = "XXXXXXXX";
            String rememberme = "on";
            String query = String.format("postback=%s&user=%s&password=%s&rememberme=%s"
                    , URLEncoder.encode(postback, charset)
                    , URLEncoder.encode(user,charset)
                    , URLEncoder.encode(password, charset)
                    , URLEncoder.encode(rememberme, charset));

            connection = (HttpURLConnection)url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept-Charset", charset);
            connection.setDoOutput(true);           
            connection.setFixedLengthStreamingMode(query.length());

            out = connection.getOutputStream ();
            out.write(query.getBytes(charset));

            if (connection.getHeaderFields() == null){
                System.out.println("Header null");
            }else{
                for (String cookie: connection.getHeaderFields().get("Set-Cookie")){
                    System.out.println(cookie.split(";", 2)[0]);
                }
            }
        } catch (IOException e){
            e.printStackTrace();
        } finally {
            try { out.close();} catch (IOException e) { e.printStackTrace();}
            connection.disconnect();            
        }

所以输出是:

    login_key=20ad8177db4eca3f057c14a64bafc2c9
    FASID=cabf20cc471fcacacdc7dc7e83768880
    track=30c8183e4ebbe8b3a57b583166326c77
    client-data=%7B%22ism%22%3Afalse%2C%22showm%22%3Afalse%2C%22ts%22%3A1349189669%7D

ANDROID 代码:这进入 doInBackground AsyncTask 主体

HttpURLConnection connection = null;
            OutputStream out = null;
            try {                   
                URL url = new URL("http://www.XXXXXXXXXXXXXX.php");         
                String charset = "UTF-8";       

                String postback = "1";
                String user = "XXXXXXXXX";
                String password = "XXXXXXXX";
                String rememberme = "on";
                String query = String.format("postback=%s&user=%s&password=%s&rememberme=%s"
                        , URLEncoder.encode(postback, charset)
                        , URLEncoder.encode(user,charset)
                        , URLEncoder.encode(password, charset)
                        , URLEncoder.encode(rememberme, charset));

                connection = (HttpURLConnection)url.openConnection();
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Accept-Charset", charset);
                connection.setDoOutput(true);           
                connection.setFixedLengthStreamingMode(query.length());

                out = connection.getOutputStream ();
                out.write(query.getBytes(charset));

                if (connection.getHeaderFields() == null){
                    Log.v(TAG, "Header null");
                }else{
                    for (String cookie: connection.getHeaderFields().get("Set-Cookie")){
                        Log.v(TAG, cookie.split(";", 2)[0]);
                    }
                }
            } catch (IOException e){
                e.printStackTrace();
            } finally {
                try { out.close();} catch (IOException e) { e.printStackTrace();}
                connection.disconnect();            
            }

而且这里没有输出,似乎connection.getHeaderFields() 没有返回结果。显示日志至少需要 30 秒:

10-02 16:56:25.918: V/class com.giorgi.myproject.activities.HomeActivity(2596): Header null

在 GALAXY NEXUS 上测试

4

4 回答 4

3

我已经弄清楚是什么问题了。似乎使用 Java Desktop 时,FollowRedirects 标志默认为 false (我想),而在 Android 中则为 true。getInstanceFollowRedirects 在这两种情况下都是 TRUE,所以我真的不知道为什么它以不同的方式工作,但没关系,解决方案是完美的。

所以它没有捕获 POST 请求的响应,它遵循一些重定向并试图从另一个 GET 自动请求中获取响应。

解决方案是:connection.setInstanceFollowRedirects(false);


我知道这一点的方法是使用网络监视器查看网络流量:

从桌面应用程序监控此流量:

23  10:08:50 03/10/2012 1.3944670   javaw.exe   192.168.1.36    www.XXXXXXXXX.com   HTTP    HTTP:Request, POST /es/login.php    {HTTP:8, TCP:7, IPv4:6}
24  10:08:50 03/10/2012 1.3954741   javaw.exe   192.168.1.36    www.XXXXXXXXX.com   HTTP    HTTP:HTTP Payload, URL: /es/login.php   {HTTP:8, TCP:7, IPv4:6}
32  10:08:50 03/10/2012 1.9811257   javaw.exe   www.XXXXXXXXX.com   192.168.1.36    HTTP    HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php  {HTTP:8, TCP:7, IPv4:6}

为了监控 Android 应用程序中的流量,我不得不在模拟器而不是手机中运行它。结果是:

60  9:59:34 03/10/2012  4.0285909   emulator-arm.exe    192.168.1.36    XX.XX.XXX.XXX   HTTP    HTTP:Request, POST /es/login.php    {HTTP:13, TCP:12, IPv4:11}
65  9:59:34 03/10/2012  4.1524735   emulator-arm.exe    192.168.1.36    XX.XX.XXX.XXX   HTTP    HTTP:HTTP Payload, URL: /es/login.php   {HTTP:13, TCP:12, IPv4:11}
75  9:59:35 03/10/2012  4.6276286   emulator-arm.exe    XX.XX.XXX.XXX   192.168.1.36    HTTP    HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php  {HTTP:13, TCP:12, IPv4:11}
77  9:59:35 03/10/2012  4.7095994   emulator-arm.exe    192.168.1.36    XX.XX.XXX.XXX   HTTP    HTTP:Request, GET /es/login.php, Query:FASID=a5e39f35325499e060f43d35bc956a45   {HTTP:13, TCP:12, IPv4:11}
311 9:59:55 03/10/2012  24.8355823  emulator-arm.exe    XX.XX.XXX.XXX   192.168.1.36    HTTP    HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php  {HTTP:13, TCP:12, IPv4:11}
313 9:59:55 03/10/2012  24.9384843  emulator-arm.exe    192.168.1.36    XX.XX.XXX.XXX   HTTP    HTTP:Request, GET /es/main.html, Query:FASID=a5e39f35325499e060f43d35bc956a45   {HTTP:13, TCP:12, IPv4:11}
317 9:59:55 03/10/2012  25.0535818  emulator-arm.exe    XX.XX.XXX.XXX   192.168.1.36    HTTP    HTTP:HTTP Payload, URL: /es/main.html   {HTTP:13, TCP:12, IPv4:11}

因此,应用后**connection.setInstanceFollowRedirects(false);**的结果是预期的:

61  10:30:43 03/10/2012 4.9211205   emulator-arm.exe    192.168.1.36    XX.XX.XXX.XXX   HTTP    HTTP:Request, POST /es/login.php    {HTTP:14, TCP:13, IPv4:12}
64  10:30:43 03/10/2012 5.0362501   emulator-arm.exe    192.168.1.36    XX.XX.XXX.XXX   HTTP    HTTP:HTTP Payload, URL: /es/login.php   {HTTP:14, TCP:13, IPv4:12}
70  10:30:43 03/10/2012 5.5103384   emulator-arm.exe    XX.XX.XXX.XXX   192.168.1.36    HTTP    HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php  {HTTP:14, TCP:13, IPv4:12}

感谢您的所有回答和兴趣。

于 2012-10-03T08:46:06.687 回答
0

这可能与网络尝试在模拟器或手机的移动浏览器中打开您请求的地址有关。

于 2012-10-02T15:21:58.790 回答
0

确保您已在 AndroidManifest.xml 文件中添加了所需的权限。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
于 2012-10-02T15:35:53.350 回答
0

我遇到了很多麻烦HTTPURLConnection尝试了几天后,我发现设置标题的顺序很重要。这对我有用。

            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Host", "yoursite.com");
            conn.setRequestProperty("Authorization", "Basic " + Base64.encodeToString(toencode, Base64.DEFAULT));
            conn.setRequestProperty("Accept-Charset", "UTF-8");

            conn.setConnectTimeout (5000) ; 
            conn.setDoOutput(true); 
            conn.setDoInput(true); 

它应该适合你。

于 2012-10-02T21:20:35.830 回答