使用JQuery AJAX向Android NanoHTTPd POST JSON数据,无法获取请求体?
问题原因及解决步骤
一、服务器端无法获取JSON POST数据的原因及修复
你当前用session.getQueryParameterString()和session.getParms()获取数据,但这两个方法仅适用于**表单编码(application/x-www-form-urlencoded)**的POST请求,而你发送的是application/json格式的请求体,所以无法拿到数据。
修复后的服务器端代码:
if (uri.equals("/data")) { try { // 读取请求输入流,获取JSON体 InputStream inputStream = session.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } String postBody = sb.toString(); // 解析JSON(Android自带org.json库) JSONObject jsonObject = new JSONObject(postBody); String appName = jsonObject.getString("AppName"); String enabled = jsonObject.getString("Enabled"); System.out.println("POST JSON内容: " + postBody); System.out.println("AppName: " + appName); // 返回JSON格式响应,适配AJAX的dataType要求 return newFixedLengthResponse( NanoHTTPD.Response.Status.OK, NanoHTTPD.MIME_JSON, "{\"status\":\"success\",\"message\":\"It was good!\"}" ); } catch (IOException e) { e.printStackTrace(); return newFixedLengthResponse(NanoHTTPD.Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_JSON, "{\"status\":\"error\",\"message\":\"IO异常\"}"); } catch (JSONException e) { e.printStackTrace(); return newFixedLengthResponse(NanoHTTPD.Response.Status.BAD_REQUEST, NanoHTTPD.MIME_JSON, "{\"status\":\"error\",\"message\":\"JSON解析失败\"}"); } catch (ResponseException e) { e.printStackTrace(); return newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND, NanoHTTPD.MIME_JSON, "{\"status\":\"error\",\"message\":\"请求路径错误\"}"); } }
注意:
- 无需调用
session.parseBody(),直接读取原始输入流即可获取JSON请求体。 - Android SDK自带
org.json包,无需额外引入第三方库。
二、AJAX触发错误回调的原因及修复
你的AJAX设置了dataType: 'json',意味着jQuery会期望服务器返回JSON格式响应,但当前服务器返回的是纯文本类型,jQuery解析JSON失败就会触发error回调。
修复后的AJAX代码(两种可选方案):
方案1:保持dataType为json,匹配服务器JSON响应(推荐)
保留AJAX的dataType: 'json',配合上面修改后的服务器代码,可直接解析响应JSON:
var reqData = JSON.stringify({"AppName": "test", "Enabled": "yes" }); $.ajax('http://10.0.2.16:8765/data', { data: reqData, dataType: 'json', contentType: "application/json", async: true, // 不推荐同步请求,改为异步避免阻塞浏览器 type: 'POST', success: function (data) { alert(data.message); // 直接读取JSON字段 }, error: function (jqXHR, textStatus, errorThrown) { alert("错误:" + errorThrown + " 请求数据:" + reqData); } });
方案2:修改dataType为text,适配纯文本响应
如果不想修改服务器返回格式,将AJAX的dataType改为text:
var reqData = JSON.stringify({"AppName": "test", "Enabled": "yes" }); $.ajax('http://10.0.2.16:8765/data', { data: reqData, dataType: 'text', contentType: "application/json", async: true, type: 'POST', success: function (data) { alert(data); // 直接显示纯文本响应 }, error: function (jqXHR, textStatus, errorThrown) { alert("错误:" + errorThrown + " 请求数据:" + reqData); } });
额外建议
- 尽量避免使用
async: false,同步请求会阻塞浏览器主线程,严重影响用户体验。 - 服务器端返回响应时,务必保证
Content-Type与返回内容格式一致,避免客户端解析异常。
内容的提问来源于stack exchange,提问作者StealthRT
相关产品推荐
相关产品推荐

