我试图通过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 CODE:这里面是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上测试
答案 0 :(得分:3)
我发现了问题所在。 似乎使用Java Desktop,标志FollowRedirects默认是假的(我想),而在Android中它是真的。两种情况下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}
感谢您的所有答案和兴趣。
答案 1 :(得分:0)
可能是网络试图在模拟器或手机的移动浏览器中打开您要求的地址。
答案 2 :(得分:0)
确保您已在AndroidManifest.xml文件中添加了所需的权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
答案 3 :(得分: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);
它应该适合你。