1需求
目前在维护一个项目。接到一个需求是要在某个保存动作之前增加一步校验,如果校验通过则可以进行保存,否则返回错误提示并阻止保存动作。
因为是寄存项目,保存动作是通过js提交表单发送请求动作,所以在不改变其业务逻辑的前提下,我选择了在保存之前使用jQuery ajax增加一个校验方法。success回调处从后端拿到一个JSON格式的响应,包含一个布尔类型的flag。
demo如下:
function chkXXX(name){
var result;
$.ajax({
type:"post",
url:"chkXXX.do",
dataType:"json",
data: $("#add_form").serialize(),
async:false,
success:function(backdata){
var r = jQuery.parseJSON(backdata);
result = r;
},
error:function(xhr, status, e){
alert(status);
}
});
return result;
}
在三下五除二快速搞定上线后,隔天运维MM就接到反馈,告知此功能并没有work。。。(我靠,不可能吧。写过辣么多类似的校验,怎么就你罢工了呢)
开始以为是浏览器兼容性问题,因为遇到好多此种情况(比如有些情况在 win7 ie8可以,但在xp ie8 就不行),但是我在使用ie,chrome调试以后发现都不正常,
这个时候开启chrome的F12,报错信息提示 返回的flag 为null,但是我后端明明只返回true,false两种情况,这个时候基本确定问题就出在前端了。
断点debug,跟踪到的resut 确实是null,非后台JSON。看来问题就定位到:
var r = jQuery.parseJSON(backdata);
3原因
其实问题的根本原因还是在于自己对ajax原理的不熟悉。
这里我忽略一个细节,就是我在设置请求属性的时候,设置了:
dataType:"json",
var r = jQuery.parseJSON(backdata);
冲突了。
预期服务器返回的数据类型。
如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML。在 1.4 中,JSON 就会生成一个 JavaScript 对象,而 script 则 会执行这个脚本。随后服务器端返回的数据会根据这个值解析后,传递给回调函数。可用值:
"xml": 返回 XML 文档,可用 jQuery 处理。
"html": 返回纯文本 HTML 信息;包含的 script 标签会在插入 dom 时执行。
"script": 返回纯文本 JavaScript 代码。不会自动缓存结果。除非设置了 "cache" 参数。注意:在远程请求时(不在同一个域下),所有 POST 请求都将转为 GET 请求。(因为 将使用 DOM 的 script标签来加载)
"json": 返回 JSON 数据 。
"jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。
"text": 返回纯文本字符串
设置dataType以后,返回的数据类型就已经是JSON对象了,再使用jq转换就出错了。
4解决
既然知道原因了,就知道解决方案了
其一就是设置dataType属性后,直接返回backdata;
其二则是不设施dataType,返回JSON格式的字符串,然后手动转换成JSON对象;
5总结
走过的路,踩过的坑。以后还需努力啊!