Android应用请求返回HTML而非JSON,解析失败求排查
问题分析与解决方案
我来帮你梳理下导致服务器返回HTML而非预期JSON的核心问题,以及对应的解决办法:
1. 请求头与请求体格式不匹配
你明明设置了Content-Type: application/json请求头,但却用UrlEncodedFormEntity来封装参数——这个类是专门生成application/x-www-form-urlencoded格式的表单数据的,和你声明的JSON类型完全不匹配。服务器收到这种“头不对身”的请求后,无法正确解析你的参数,因此返回了验证页面而非预期的JSON响应。
修正方法:
如果服务器确实要求JSON格式的请求体,你需要将参数转换成JSON字符串,用StringEntity来封装:
public JSONObject getJSONFromUrl(String url, List<NameValuePair> params ) { JSONObject jObj = null; String json = ""; InputStream is = null; try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); // 将参数列表转换为JSON对象 JSONObject jsonParams = new JSONObject(); for (NameValuePair param : params) { jsonParams.put(param.getName(), param.getValue()); } // 创建JSON格式的请求实体 StringEntity entity = new StringEntity(jsonParams.toString(), "UTF-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException | JSONException e) { e.printStackTrace(); } // 读取响应内容 try { BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); json = sb.toString(); Log.e("JSON", json); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } // 解析JSON对象 try { jObj = new JSONObject(json); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } return jObj; }
2. 服务器的反爬/浏览器验证机制
从返回的HTML内容能看出,服务器正在做浏览器身份验证:它通过JavaScript生成一个加密的__test Cookie,要求客户端设置该Cookie后再重定向。你的HttpClient请求没有处理这个验证逻辑,所以服务器直接返回了验证页面。
处理方案:
你需要先完成这个验证流程,再发起目标POST请求:
- 第一步:获取并解密
__testCookie
可以解析返回HTML中的AES参数(a、b、c三个数组),手动实现slowAES.decrypt逻辑得到Cookie值;或者用WebView加载该页面,让WebView自动执行JS并设置Cookie,再从WebView的CookieManager中提取Cookie。 - 第二步:携带Cookie发起POST请求
在HttpPost请求中添加Cookie头,或者让HttpClient通过CookieStore自动管理Cookie。
另外提醒下:DefaultHttpClient已经被官方废弃,建议改用更现代的OkHttp库,它处理Cookie、请求头和复杂验证场景会更简洁高效。
内容的提问来源于stack exchange,提问作者Neelu Kalani
相关产品推荐
相关产品推荐

