HTTP POST 提交问题

最近用http+post方式实现了系统间数据交互的需求.
常用的方式是 application/json方式直接post json对象 . 告诉服务器数据格式将会是
  1. { Name : 'John Smith', Age: 23}

  1. {"siteId":"ZHAN20160329TDLXJND144649","apiSecret":"userid123","workNumber":"FJ-8006-160912-1715-00001","fluetype":"2","apiKey":"yyxt"}
后台可以直接springmvc直接接收并转为相关vo对象处理.

而在手机与后台交互的场景中遇到一种格式要求
  1. 方法名称:appScanBuildingData
  2. 请求:json字符串形式,最外层用data包裹
demo格式范例是
  1. data={"alarmDetail":[{"address":"中国","cgi":"CGI0"},{"address":"米国","cgi":"CGI1"},{"address":"日本","cgi":"CGI2"}],"areaCode":"350723","cellNumber":"1599999","cityCode":"350723","lat":"232.545","lon":"98.233","workNO":"ZB33000333337"}
这两种数据需要有什么区别? 

原因在于Content-Type 中application/x-www-form-urlencoded 和application/json的设置问题, 他们所代表传输的数据格式不同.



这种格式要求其实使用的Content-Type: 应该为application/x-www-form-urlencoded;

即提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码.
  1. POST http://www.example.com HTTP/1.1
  2. Content-Type: application/x-www-form-urlencoded;charset=utf-8
  3. title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3


所以注意, 协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。下面就正式开始介绍它们。(application/json , application/x-www-form-urlencoded, 等等)
  • 当以application/json的content-type传送数据,被传送的对象只需被json序列化。
消息主体中的格式
  1. { Name : 'John Smith', Age: 23}

  • 当以application/x-www-form-urlencoded的方式传送数据。请求的内容需要以..=..&..=..的格式提交,在请求体内内容将会以”&”和“ = ”进行拆分。
消息主体中的格式
  1. Name=John+Smith&Age=23

  • application/json请求时,Springmvc可以直接处理转换为对象.
  • application/x-www-form-urlencoded方式传输,后台接收时候可以采用
  1. String data = request.getParameter("data"); 这样的方式来接受json格式的数据.
  2. 然后在转为Object使用:
  3. AlarmInfo vo=null;
  4. vo=JSONObject.parseObject(data, AlarmInfo.class);

约定这种格式的初衷估计就是后台为接收数据方便的考虑.
综上
  1. data={"alarmDetail":[{"address":"中国","cgi":"CGI0"},{"address":"米国","cgi":"CGI1"},{"address":"日本","cgi":"CGI2"}],"areaCode":"350723","cellNumber":"1599999","cityCode":"350723","lat":"232.545","lon":"98.233","workNO":"ZB33000333337"}
其实和data=John 没本质区别.不过一个值是john的字符串.一个值是json对象数组格式的字符串. fuck.


此外梳理一下js的post请求
以下针对请求端进行一下说明, jsp中Jquery的提交为例: (参考https://segmentfault.com/a/1190000004982390)
$.ajax常见的格式:
  1. $.ajax({
  2. url: "mydomain.com/url",
  3. type: "POST",
  4. dataType: "xml/html/script/json", // expected format for response
  5. contentType: "application/json", // send as JSON
  6. data: $.param( $("Element or Expression") ), //或者采取其他$()的方法处理数据(serializearray())
  7. complete: function() {
  8. //called when complete
  9. },
  10. success: function() {
  11. //called when successful
  12. },
  13. error: function() {
  14. //called when there is an error
  15. },
  16. });

jQuery中默认的表单提交方式为application/x-www-form-urlencoded,与XMLHttpRequest不同的地方在于:数据的URL方式编码,由jQuery来做,只需要在$.ajax({})参数中设置processData = true(这也是默认,可省略)。
  1. /* dataToSend为Object类型的表单数据,否则jQuery会抛出异常 */
  2. $.ajax({
  3. method: 'POST',
  4. url: '...',
  5. data: dataToSend,
  6. contentType: 'application/x-www-form-urlencoded', // 可省略
  7. processData: true, // 可省略
  8. success: function() {...}
  9. });
  10. 注意:若采用GET方式,则将method改为GET即可,不需要在url后面加上数据。
比如: 例子来源http://hayageek.com/jquery-ajax-form-submit/
html
  1. <form name="ajaxform" id="ajaxform" action="ajax-form-submit.php" method="POST">
  2. First Name: <input type="text" name="fname" value =""/> <br/>
  3. Last Name: <input type="text" name="lname" value ="" /> <br/>
  4. Email : <input type="text" name="email" value=""/> <br/>
  5. </form>
js
  1. $("#ajaxform").submit(function(e)
  2. {
  3. var postData = $(this).serializeArray();
  4. var formURL = $(this).attr("action");
  5. $.ajax(
  6. {
  7. url : formURL,
  8. type: "POST",
  9. data : postData,
  10. contentType: 'application/json',
  11. success:function(data, textStatus, jqXHR)
  12. {
  13. },
  14. error: function(jqXHR, textStatus, errorThrown)
  15. {
  16. }
  17. });
  18. e.preventDefault(); //STOP default action
  19. });
  20. $("#ajaxform").submit(); //SUBMIT FORM
提交的数据
{"fname":"Ravi","lname":"Shanker","email":"xx@xxx.com"}
----------------------

备注:

  • $(selector).serialize() 序列表表格内容为字符串,用于 Ajax 请求。可以对整个form,也可以只针对某部分。

  1. $('#form').submit(function(event){
  2. event.preventDefault();
  3. $.ajax({
  4. url:' ',
  5. type:'post',
  6. data:$("form").serialize(),
  7. }

  • $(selector).serializeArray()

serializeArray() 方法序列化表单元素(类似 .serialize() 方法),返回 JSON 数据结构数据。

注意:此方法返回的是 JSON 对象而非 JSON 字符串。需要使用插件或者第三方库进行字符串化操作。

返回的 JSON 对象是由一个对象数组组成的,其中每个对象包含一个或两个名值对 —— name 参数和 value 参数(如果 value 不为空的话)。举例来说:

[ 
  {name: 'firstname', value: 'Hello'}, 
  {name: 'lastname', value: 'World'},
  {name: 'alias'}, // 值为空
]

.serializeArray() 方法使用了 W3C 关于 successful controls(有效控件) 的标准来检测哪些元素应当包括在内。特别说明,元素不能被禁用(禁用的元素不会被包括在内),并且元素应当有含有 name 属性。提交按钮的值也不会被序列化。文件选择元素的数据也不会被序列化。

该方法可以对已选择单独表单元素的对象进行操作,比如 <input>, <textarea>, 和 <select>。不过,更方便的方法是,直接选择 <form> 标签自身来进行序列化操作。

  1. $("form").submit(function() {
  2. console.log($(this).serializeArray());
  3. return false;
  4. });
  5. 上面的代码产生下面的数据结构(假设浏览器支持 console.log):
  6. [
  7. {
  8. name: a
  9. value: 1
  10. },
  11. {
  12. name: b
  13. value: 2
  14. },
  15. {
  16. name: c
  17. value: 3
  18. },
  19. {
  20. name: d
  21. value: 4
  22. },
  23. {
  24. name: e
  25. value: 5
  26. }
  27. ]
  • $.params() $.param()方法是serialize()方法的核心,用来对一个数组或对象按照key/value进行序列化。

序列化一个 key/value 对象:

var params = { 1900, height:1200 };
var str = jQuery.param(params);
$("#results").text(str);

结果:

width=1680&height=1050

单个对象可以才用
JSON.parse()和JSON.stringify()处理
1.parse 用于从一个字符串中解析出json 对象。例如
var str='{"name":"cpf","age":"23"}'
经 JSON.parse(str) 得到:
Object: age:"23"
name:"cpf"
_proto_:Object
ps:单引号写在{}外,每个属性都必须双引号,否则会抛出异常

2.stringify用于从一个对象解析出字符串,例如
var a={a:1,b:2}
经 JSON.stringify(a)得到:
“{“a”:1,"b":2}”





原文地址:https://www.cnblogs.com/redcoatjk/p/5976683.html